BBC (Brian's Boot Camp)

Not to be confused with the British Broadcasting Corporation, the BBC will focus on Brian's fast paced journey of the mastery of the Java programming language.

Thursday, February 24, 2005

Parsing a string for boolean

In the examples in the 21 Days book, there are numerous instances where a String is parsed to produce some other value type like an int or a float using a statement such as i = int.parseInt(string). This makes perfect sense to me.

One of the exercises says this: Create a modified version of the Storefront project that includes a noDiscount variable for each item. When this variable is true, sell the item at the retail price.
Seems simple enough. I took the GiftShop class which defines the items for sale and added a "TRUE" or "FALSE" to each of them; that's not where the problem is. Through a couple of method calls the string values assigned to each item in GiftShop get handed off to an Item class. Item takes all of the strings from GiftShop and assigns them to String variables or parses them and assigns them to ints or doubles. Both of those two operations use the following two statements:
retail = Double.parseDouble(retailIn);
quantity = Integer.parseInt(quanIn);

Pretty straightforward at this point.

So I get to thinking, "Well I know that ints and doubles are primitive but that there are objects which correspond to each of the primitives; that's what the whole Double.parseDouble bit is about. I know there is also a Boolean object, so I'll do the same thing for my noDiscount variable: I'll use something like this:
private boolean = noDiscount;
/* unrelated code
when the String values come in from GiftShop, the "TRUE" or "FALSE" value comes in as "String discountIn"
so then I do this: */
noDiscount = Boolean.parseBoolean(discountIn);


But it doesn't work. When I compile the class, I get the following error back:

Item.java:18: cannot resolve symbol
symbol : method parseBoolean (java.lang.String)
location: class java.lang.Boolean
noDiscount = Boolean.parseBoolean(discountIn);
^
1 error


But when I look at the API documentation, the method is there and is listed exactly the same as is the equivalent method for Integer:
static boolean | parseBoolean(String s) | Parses the string argument as a boolean.
and
static int | parseInt(String s) | Parses the string argument as a signed decimal integer.

What gives?

Monday, February 21, 2005

Another small milestone

While I'm waiting for Outlook to launch, I'll throw this up. At the beginning of the 21 Days book, the author states that the portability of Java's code allows developers to Write one, debug everywhere; funny. So far, any code that I've used for any assignments, examples, or exercises has worked fine on my laptop (where I'm using Eclipse) or on my Mac (where I'm using vim and the command line tools). Until chapter 9 which introduces Swing. The classes would compile fine on either platform, but when I ran them on OS X, I'd get the following output:

Exception in thread "main" java.lang.Error: Do not use FormatFrame.add() use FormatFrame.getContentPane().add() instead
at javax.swing.JFrame.createRootPaneException(JFrame.java:465)
at javax.swing.JFrame.addImpl(JFrame.java:491)
at java.awt.Container.add(Container.java:307)
at FormatFrame.(FormatFrame.java:24)
at FormatFrame.main(FormatFrame.java:29)

shell returned 1

I managed to track the problem down to the line add(panel); which added a JPanel to JFrame FormatFrame. Based on the error, it looked like the runtime environment wanted the getContentPane().add() method used rather than the add() method. Sure enough; altered that line of code and it compiled and ran successfully. Huzzah! On to chapter 10...

A Question of Style

Our friend Paul is right is point out that a budding Java developer should be pointed toward the Java Style Guide early to reinforce those positive style habits.

Java in 21 Days Topics

During an offline conversation with Sten (well, it was through e-mail so I guess even it was online) we discussed posting the chapter topics for the Java in 21 Days book that I'm working through. So here they are, by week:


  1. Week 1


    1. Day 1: Getting Started with Java

    2. Day 2: The ABCs of Programming

    3. Day 3: Working with Objects

    4. Day 4: Lists, Logic, and Loops

    5. Day 5: Creating Classes & Methods

    6. Day 6: Packages, Interfaces, and Other Class Functions

    7. Day 7: Threads, Exceptions, and Assertions


  2. Week 2

    1. Day 8: Data Structures

    2. Day 9: Working with Swing

    3. Day 10: Building a Swing Interface

    4. Day 11: Responding to User Input

    5. Day 12: Arranging Components on a User Interface

    6. Day 13: Using Color, Fonts, and Graphics

    7. Day 14: Writing Java Applets and Java Web Start Applications

  3. Week 3

    1. Day 15: Working with Input and Output

    2. Day 16: Serializing and Examining Objects

    3. Day 17: Communicating Across the Internet

    4. Day 18: JavaSound

    5. Day 19: Creating and Using JavaBeans

    6. Day 20: Reading and Writing Data Using JDBC and XML

    7. Day 21: Writing Java Servlets and JavaServer Pages



I think the chapter names are fairly descriptive as far as what they cover, but it would take me forever to post all of the subtopics for all of the chapters. If any clarification is required, please let me know and I'll drill down where necessary. I'm just about to start reading Day 9. Like right this very minute...

Friday, February 18, 2005

A Personal Milestone

Well, I'm very excited. I called in Java...er...sick to work on Java today. Slow going, but I made progress. After spending a while reading, I went back to do the exercises from the chapters. I instantly recognized the first exercise: it was the one that basically made me decide a few months ago that, if I couldn't make the time to study every day, it wasn't worth going after. If only I'd known then what I know now...

So I struck out with my pencil and paper. Sometimes I am amazed how much clear thinking can be done with a piece of blank paper and a pencil rather than typing things out on screen. Here is the assignment:
Using the countDays() method from the DayCounter application, create an application that displays every date in a given year in a single list from January 1 to December 31.

The last time I worked on this exercise, I struggled with it for hours. Compiling what I thought would work again and again just to find that the code wouldn't compile each and every time. This time, after a little pencil work (just for the record, 5 lines of pseudocode and three lines of actual code), I took DayCounter and fashioned it into a functioning application in about twenty minutes. The only compiler error I got was because I had left the ";" off the m++;. I'm so excited! Here is the code; I used the countDays method without altering it.

class ExerciseOne {
public static void main(String[] arguments) {
int yearIn = 2004;
int m = 1;
int d = 0;

if (arguments.length > 0)
yearIn = Integer.parseInt(arguments[0]);

while (m < 13) {
d = countDays(m, yearIn);
for (int i = 1; i < d + 1; i++) {
System.out.println(m + "/" + i + "/" + yearIn);
}
m ++;
}
}

static int countDays(int month, int year) {
int count = -1;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
count = 31;
break;
case 4:
case 6:
case 9:
case 11:
count = 30;
break;
case 2:
if (year % 4 == 0)
count = 29;
else
count = 28;
if ((year % 100 == 0) & (year % 400 != 0))
count = 28;
}
return count;
}
}

Huzzah!

Assignment #3: Time to put the G in GUI

When you feel ready to bone up on GUIs, you can tackle this one:

Write a program that displays two text fields and a button in a frame; the layout is up to you. When the button is pressed, it should take the contents from the first text field and display them reversed in the second text field.

Here's a quick mock-up as an example:


Extra Credit: Write it with Swing (pictured), then write it again using the AWT.

Bonus Extra Credit: Write it as one program that takes an input argument on the command line, either -swing or -awt, and display the frame using the appropriate toolkit. Share as much code as possible between the two implementations. Don't get hung up on this one, the important thing here is to expose you to windowing programming.

Thursday, February 17, 2005

Assignment #2: Hot Date, A Date, Dinner with Friends, Dinner Alone

Write a program that takes three command line arguments as numbers, a month, a day, and a year and prints out the "human readable" date. Example input: 2 11 1975, example output: February 11, 1975.

Here's the catch though, don't just map numbers to months, (i.e. if (month == 1) str = "January"... Rather use some combination of the following classes:

java.util.Calendar
java.util.GregorianCalendar
java.text.SimpleDateFormat

You can look up the useage of these classes in the API documentation (see the school of hard docs post for more info on that). This is a non-trivial program as it is your first foray into class usage. I don't expect you to just do it and post the answer -- so by all means, post questions along the way.

Assignment #1 Answer

Well, here is my solution to The Final Countdown assignment:

class FinalCountdown {
public static void main(String[] arguments) {
int d = 100;

do {
if (0 == d % 5)
System.out.println(d);
d--;
} while (d > -1);

}
}

As I had begun to releate to Sten, I was having a heck of a time with this. Initially, I thought I would want to use two classes -- one that looped & counted and one that did the math and would then print out the lines -- but I thought I should try to make it work in a single class.

What I had difficulty with was the loop type. Initially, I was using a for loop. But no matter what I did, I couldn't get any output from the loop itself. When I changed to the do-while loop, there was suddenly output. The for version looks like this; I added a couple of lines to confirm whether it was actually getting through the whole thing or not:
class FinalCountdown2 {
public static void main(String[] arguments) {
int d;
System.out.println("Starting the loop.");
for (d = 100; d == 0; d--) {
if (0 == d % 5)
System.out.println(d);
}
System.out.println("Ending the loop.");
}
}

Wednesday, February 16, 2005

Currency Conundrum

In the spirit of illustrating the inaccuracies of floating point math, this is a great example from the book Effective Java:

Question: How many items can you buy if you have $1 if each item you buy costs 10 cents more than the previous purchase, starting at 10 cents?

The answer is 4 items (one item for .10, .20, .30, and .40, all add up to $1). A pretty straight forward math problem involving only four operations and one decimal place. However if you implement the solution using doubles (the highest primitive precision floating point available) thusly:

double funds = 1.00;
int itemsBought = 0;
for (double price = 0.10; funds >= price; price += 0.10) {
funds -= price;
itemsBought++;
}

You will get the itemsBounght equal to 3. Why? Because of a cumulative rounding error even after just three operations. When the loop test comes around for the forth time price is 0.4, but funds is only 0.3999999999999999. In practice this would be rounded up to 0.4 if you were going to display it, but since it's not here, it fails the comparison test.

The moral of this story is: Be mindful of how you use floating point numbers. If exact answers are required use integral data types, or a custom object capable of holding larger scaled numbers (I.E. BigDecimal).

Since money is an important thing to get right, when I implemented the accounting part of Iris, I wrote the Money class as a wrapper around BigDecimal. All math operations using money use the Money class. There have been several (well, 2) occassions where other parties have come up with different invoice amounts when manually calculating invoices out of Iris -- and Iris has proved to be right in both cases.

Here's the answer to that programming problem using the Money class:

int itemsBought = 0;
Money funds = new Money(1.0);
for (Money price = new Money(0.1); funds.compareTo(price) >= 0;
price = price.add(new Money (0.1))) {

  itemsBought++;
  funds = funds.subtract(price);
}

Which gives the correct answer of 4.

Tuesday, February 15, 2005

Of ints and bits

To clarify the "which data type to use when" issue, here are some rules of thumb (or rule of thumbs). See the comment to your previous post for a more full bodied explanation of why.

1) Use doubles for floating point numbers
2) Use ints for whole numbers.
3) Rarely use float, and almost never use short, byte, char, etc.
4) When using division, divide by doubles, even if you're dividing two ints. If integer division is used, the remainder will be truncated. Unless this is desired, use doubles (i.e. int1 / (int2 * (1.0)), or int1 / (double) int2).
5) You can always cast your answer to whatever result data type you need (the above example uses a cast).

Casting in a nutshell -- consider the following:

int a = 10.0 / 2.0;

You know this answer will be 5 even, but you'll get a "loss of precision" compiler error because double division requires a double result. Here's how to get around that error:

int a = (int) (10.0 / 2.0);

This casts the result to an int (truncating any remainder were there one). A cast is a way of taking the safety off of the type checking. You're telling the compiler that you explicitly acknowledge the fact that you are narrowing the data type.

The above is an explicit cast. Implicit casts happen without warning or compiler errors:

double d = 10 / 2;

The above result is normally an integer, but you're implicitly casting it to a double. Since this is a widening of data type, and no precision will be lost, an explicit cast is not needed.

A programmer is born...

I'm about to respond to your questions as comments to the relevent post, but I wanted to write this observation as its own post:

I'm extremely encouraged by your questions. You're asking very detailed questions about subtle nuances of the language that many people would choose to gloss over. The fact that you are frustrated by this shows me:

1) Certification will not be a problem for you since you're hung up on the details.

2) You will most likely make an excellent programmer since programming is *all* about the details. It's the people who just get it to work (or not work), call it "close enough" and then walk away that are the ones to worry about.

I knew you were a smart and dedicated guy, but you really never know how someone will take to programming. Much of the question of your ability and attitude of whether this will work out or not has just been answered for me. The rest, as they say, is just details...

Integer questions re: 2 exercises

So I managed to get up nice and early and put some good time in. I got through some 21 Days and spent some time writing some pseudocode for the "Final Countdown" assignment. I may spend lunch today focusing on that assignment since I think I have it worked out at least in my head.

But I ran into some questions about the two exercises in the chapter this morning. In both cases, I was able to fulfill the exercise, but I got slightly different results and/or couldn't use integer types that I thought I should have been able to use.

Rather than make this post super long, I'll leave it at that and post comments to this post for each of the two exercises.

Monday, February 14, 2005

The School of Hard Docs

If you haven't already, you'll probably want to download the Java API Documentation and bookmark it in your favorite browser (I.E. IE). The API documentation is an HTML reference with complete method and class listings of all classes in all packages of the core API. It's an invaluable reference that I've already referred to twice today.

When you can't remember if JCheckBox's constructor takes the String argument first, or the boolean argument, you turn to the docs.

(What does it say about the prevailance of Java when the first hit in Google for "String", a fairly common word, is the Java API doc page?)

Sunday, February 13, 2005

Assignment #1 - The Final Countdown

For reference here's Assignment #1:

Write a program (preferabley in Java) that counts backwards from 100 to 0, printing every fifth number (i.e. 100, 95, 90, etc.). You can post your answer/questions as comments to this post.

One Idea For a Plan

I don't know the official timelines, but I think it's safe to assume at least, but probably not much more than, a month. A job description needs to be assembled, other candidates will be probably be brought in for interviews -- the entire HR process can be slow moving. So I would target mid march, and if more time works out, all the better.

I don't want to sugar coat this at all -- studying the language cold with the aim of getting certified within a month is probably unrealistic. I think the best way to proceed is to keep certification in the back of your mind, but not have it as the short term goal, and rather start with a highly interactive quiz/assignment/reading cycle with me (hence this blog). I would say, consider me your personal tutor; I imagine we'll be corresponding even multiple times a day in a back and forth, answering questions, etc.

So I think the best use of your time will be to devote full attention to the programming exercises that I'll give you to work on. These will be taylored toward exposing you to different parts of the language, and will require research, but hopefully won't be too far off of the previous assignment. Imagine it as me leading you through the language highlights -- the more we can hit in our limited time, the better.

So that's where I think we should start. I think certification should be your ultimate goal -- and maybe even a condition of hire (that you would be hired uncertified, for example, but on the condition that you did within a month or two). But right now, I think that just reading cold through a book without context wouldn't be the best use of what little time there is.

If the ultimate goal is to hire someone whose abilities I feel comfortable working with, then I think the best thing to do is start that relationship now. If in a month you've made good progress, but certification is still a ways off, at least we'll have a working relationship to some extent, and that is the ultimate goal in this situation.

So having said all that, I would say try to write that "counting program" I gave you (I'll write it again as a separate post so you can post quetsions/your answer). If you're stumped on a part, or don't know where to begin, go ahead and ask. We'll keep the channels nice and open.

Saturday, February 12, 2005

Timeline & Odds

What do you know about the timeline on this hiring at this point? Shonah and I are trying to get our ducks in a row so I can put in the time that I need to. But I've got to say, I'm more than a bit daunted by the task of both getting through a cert book in two weeks -- thanks for the recommendation, by the way -- and then working on practice tests for another two-ish weeks. It is very likely that I'll try to pick up the cert book before the weekend is out.

I haven't had time to reply to your e-mail yet, but I hope to do so soon.

Since Dave appears to be here, too, I'd love to hear what kind of raw time you guys think might be necessary to accomplish getting the certification in a month. Not that I don't trust your opinion, Sten, but I certainly would be encouraged to hear a second opinion on the matter.

It should be noted that I have about 5 vacation days left that I could use toward acheiveing this goal.

Friday, February 11, 2005

Certifiably Unsane!

So it looks like the Java 1.4 certification exam is the latest programmer exam (meaning there's no 1.5 exam yet). Not a whole lot of significant changes between 1.2 and 1.4, but it probably still merits getting a recent study guide.

When I was at Borders last night, I perused this little number, which seemed heavy on the practice questions. Relatively cheap too, probably a good companion book, specifically for the last couple weeks before actually taking the exam.