Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Java Objects Delivering the MVP Validating and Normalizing User Input

in 10.20 of the video

at 10.20 in the video the boolean isAcceptable is set to true, in the try block, but i don't understand why its not set to false, since it throws the exception afterwards, afterwards there is the while loops, that return is hit while (! isAcceotable), which makes sense, but since isAcceptable is set to true, how does it even go there?

1 Answer

Jennifer Nordell
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

Hi there! The isAcceptable variable is set to true in the try block. In the try block the applyGuess method is called. Besides determining if the the guess was a hit or miss, it also calls the normalizeGuess method. This method describes what we consider to be a valid letter to guess. For example, entering a semicolon should not be a valid guess. There are two exceptions that can be thrown here. One exception is if the character entered is not a letter and the other exception is if the character has already been guessed. If the user enters a valid letter that has not already been guessed, then it will pass the normalizeGuess without throwing an error and come back to applyGuess. It's here that we determine if it was a hit or miss. If an error was not thrown, the try block will execute and there will be no error to catch. Thus isAcceptable will be set to true. When is acceptable is set to true, the while loop will cease execution.

The isAcceptable variable is set up explicitly to check to make sure that the user enters a valid letter (not a semicolon or number or some other oddity) and that it hasn't been guessed before. It will continue to get a guess until the user enters something valid. When the user has entered something valid, it checks to see if it was a hit or miss and then returns whether or not it was a hit or miss.

We start it with false because the user hasn't yet entered a guess. It's not reasonable to assume right from the start that their input was valid. Users are wildly unpredictable. We want to check the input until it is valid.

Hope this clarifies things! :sparkles:

edited for additional comment

You asked why it's not set to false in the try block. We want to set it to true if everything passed, which is the purpose of the try block. If everything passes, the body of the try should execute to completion, otherwise the error is caught. We want to get user input until there is no error. When there is no error and the user has entered something correctly, we definitely want to set isAcceptable to true so that we can return whether or not their valid input was a hit or miss. :smiley:

Hi Jennifer! Thank you for clarifying that for me. Just to get it straight... the try block doesn't execute any code, it just checks if the statement can pass, and if the statement doesn't pass the isAcceptable method will change?

Jennifer Nordell
seal-mask
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

kristoffer tølbøll Yes, the try block executes code. Also, isAcceptable is a variable and not a method. Let me see if I can try and further clarify. The try block is there to say what should happen if there are no errors to throw. It starts through the code line by line. When an error is encountered, the rest of the try block is not executed and it goes down to the catch to catch the error that was thrown.

In this instance, the try block says to first go out and do applyGuess. But inside applyGuess is a call to another function called normalizeGuess. It is here that we determine if the input was valid. If it passes all the requirements, then it returns to applyGuess with no error. This is our ideal situation. This is what we want to happen. It means the user has entered a valid letter that they have not already guessed. The applyGuess then determines if it was a hit or miss. At this point we go back to the try block. At this point, because there are no errors, we set isAcceptable to true. This means it passed all our tests and that the user input was just fine. The catch block is then skipped.

Had there been errors, it still would've returned back and skipped the rest of the try block and gone to the catch block which means the isAcceptable = true would not execute. This means that isAcceptable would still be false. That makes sense, right? If the input is invalid then a variable named isAcceptable sounds like it should be false as the input is very really not acceptable :smiley: Which means, of course, that we would repeat this entire process and we continue to do so until the input is acceptable.

try {
    isHit = game.applyGuess(guess);  // apply the game guess which also checks for errors
    isAcceptable = true;  // This executes if there were no errors otherwise we go to the catch
} catch(IllegalArgumentException iae) {  // if there was an error  ... isAcceptable is still false
    System.out.print("%s. Please try again. %n",  //print out what kind of error it was... already guessed or not a letter
        iae.getMessage());
}

The try is what happens in our ideal situation where there are no errors to throw. It goes from line to line in order, but on the first line where an error is encountered, it skips the rest and lands in the catch block.