Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed Practice Java Objects - Word Guessing Game!
You have completed Practice Java Objects - Word Guessing Game!
Preview
Let's take care of a bug we found surrounding uppercase and lowercase guesses.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
So we ran into that slight little issue
that popped up when we added
0:00
an uppercase value as input.
0:04
The uppercase value of T is different
than the lowercase value of T.
0:06
So we need to ensure a specific case
in the letters of our data.
0:10
So when dealing with input,
what our end user is
0:14
providing us through our prompts,
like those letters,
0:16
there are a few things that we can do
and should always do.
0:19
Firstly, we should check
the correctness of the input.
0:23
This is called validation.
0:26
Input that has been checked
is said to be validated.
0:27
Another option is to modify
or transform the value
0:31
so that it becomes a valid value.
0:34
This process is called normalization,
and the data is said to be normalized.
0:36
So in our, hey, you already guessed that
letter, exception example, we validated
0:41
the input and let the caller know
that the validation had failed.
0:45
Now we're looking at a place
where we need to normalize the input.
0:49
We need to normalize
alphabetic case of our values.
0:52
So what we'll do is when we start the game
with new game
0:57
treehouse,
we'll ensure that the value is lowercase.
1:00
And then we'll also make sure that anytime
someone calls apply guess on the game
1:04
object, like so, we'll take whatever
they gave us and make it lowercase too.
1:09
Sound good? Let's get to it.
1:14
Alright, I'm moving this card
right over to in progress.
1:17
Let's fix this bug.
1:20
First, let's ensure
the answer is always lowercase.
1:22
In our game,
I'll call toLowercase on our answer
1:26
that was passed in.
1:29
Now for the guess side, we need to check
1:33
if the input is actually a letter
and convert it to lowercase.
1:36
We also haven't validated
that users are entering letters at all.
1:39
At the moment,
they could enter numbers or symbols.
1:43
Let's quickly
go check out the documentation.
1:46
I'll do a Google
search for java character class.
1:49
Here we go.
1:54
So the character class
1:57
is a wrapper class for a primitive data
type char,
1:58
just like the capital I Integer class
we toyed with before, right?
2:02
So just like integer for int,
2:06
character
is used to provide helper methods for char.
2:08
And it does it through static
methods. Let's click methods here.
2:12
We're looking for something that tells us
if this is a letter.
2:16
So let's scroll through these
2:20
is methods and...
2:22
Hey, look at that.
2:25
Is letter.
2:27
It takes a char, determines
if it's a letter, and returns a boolean.
2:28
You know,
I wonder if there's something like
2:33
two lowercase that we can use on strings
for characters too.
2:35
Let's scroll down a bit more.
2:39
Wow, look at that.
2:41
We should be all set here.
2:43
Okay, so let's group our logic together
and create a private
2:47
method to handle all our input validation
and normalization.
2:50
Private methods are only acceptable
within the class itself.
2:55
They're great for grouping internal logic.
2:58
So private, it will return a char.
3:01
Let's call our method NormalizeGuess.
3:04
And that also takes in a char.
3:09
Now we'll want to throw an exception
if the provided character is not a letter.
3:15
To do this, we'll use those new tools
we saw in the character class.
3:19
Now I'll create a conditional to check
if they provided a character
3:23
that is not a letter.
3:26
So we'll throw an IllegalArgumentException
like we did before.
3:28
If not character.isLetter
3:32
and use letter.
3:42
We'll throw
3:48
a new illegal argument exception,
3:49
and we'll tell them a letter is required.
3:56
Awesome.
4:01
Now that we're certain that the provided
character is actually a letter,
4:02
we can convert it to lowercase
using character.toLowerCase. Finally, to
4:06
keep everything regarding validation
in one place, I'll move the logic
4:19
we created earlier that checks
for duplicate guesses right in here.
4:22
This ensures that our NormalizeGuess
method
4:28
is responsible for all validations
on the provided input.
4:30
After all this, I'll return the letter
so that we can use
4:34
it elsewhere.
4:37
Perfect.
4:41
We could have crammed all this
into our ApplyGuess
4:42
method, but
see how clean each method is to read now?
4:45
Separating out logic
like this can be extremely helpful.
4:48
Now, let's update
ApplyGuess to use our new method.
4:52
I'll overwrite letter
with a call to NormalizeGuess and pass
4:55
in the letter.
4:59
There we go, much cleaner.
5:05
Now let's make our prompter smarter.
5:07
Let's keep asking
until we get a valid guess.
5:09
I'll just
reorganize things a little bit here
5:12
by moving isHit
and the scanner up top of this
5:15
method.
5:18
Then let's store
a new value we'll be using to track
5:26
if we got an acceptable value.
5:28
It's a boolean and I'll call
it is acceptable
5:30
and with an initial value of false.
5:34
Perfect.
5:38
Next we'll want to create
a do while loop here.
5:39
This will ensure that it will run
at least once.
5:42
So I'll write do here above our existing
5:45
logic
5:47
and close it
right after the catch block with while.
5:51
while
5:54
and we want to run it
until is acceptable is true.
5:55
So I'll say not is acceptable,
5:59
with that exclamation mark.
6:01
In the try block here,
this will ensure we got a valid guess
6:10
so here's where I'll change
the is acceptable variable to be true.
6:13
If it wasn't valid,
this catch block would run,
6:17
is acceptable would still be false
and the loop would repeat. And this do
6:20
while loop runs at least once then
continues until we get an acceptable input.
6:24
If an exception occurs,
we show the error message and try again.
6:29
Awesome, let's try this.
6:33
Let's try entering a number.
6:40
A letter is required.
6:43
Perfect, it keeps asking.
6:44
Now let's try capital H.
6:46
It works and gets converted to lowercase
automatically.
6:48
Let's test duplicate detection
by guessing H again.
6:52
H has already been guessed.
6:55
Excellent! Great!
6:57
We fixed the case sensitivity bug
and made our input much more robust.
6:59
Our game now validates that the users
enter letters, normalizes them
7:03
to lowercase, and provides hopeful
error messages when something goes wrong.
7:07
But wait a second,
I just thought of something.
7:12
I wonder what would happen
if a user submits nothing.
7:15
Let's see.
7:19
I'll just hit enter and... Ruh-roh.
7:20
Oh, look.
7:23
It's trying to get the first character
7:24
out of the string
that doesn't have any characters.
7:26
One step forward
and one step back again, huh?
7:29
Well, we completed this bug ticket.
7:33
Great work. Let's move that over.
7:35
There's
unfortunately this new bug, though,
7:38
so let's track
that by creating a new card.
7:40
Bug. Sending no values on a guess
7:44
causes a crash.
7:47
Nice job on the looping and exception
handling.
7:56
Doing that manual testing, or QA,
which stands for quality assurance,
7:59
helped us uncover yet
another issue we should probably fix soon.
8:03
Normally, we'd also write
something called unit tests,
8:08
small bits of code
that automatically check
8:11
if other parts of our program
are working correctly.
8:13
But that's a topic
we'll explore in a later course.
8:16
As it stands, we have to do that ourselves
every single time the code changes.
8:19
Alright, let's refactor and clean up
that code right after this exercise.
8:24
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up