Old version
This is the CS 112 site as it appeared on May 12, 2022.
Problem Set 2 FAQ
If you don’t see your question here, try Piazza (using its search feature first!) or come to office hours. See the links in the navigation bar for both of those options.
-
In the material about
String
objects in Problem 2, you mention that we need to use anequals
method to compare twoString
objects to see if they are equivalent. What about comparisons ofchar
values?char
values are primitives, so they are compared using the==
operator. -
I’m constructing one of the expressions for Problem 2, and I need to convert a single character to its uppercase equivalent. However, because
char
s are primitives, they don’t have atoUpperCase
method. What can I do?Instead of using
charAt
to get achar
for the single character, usesubstring
to get aString
object of length 1. For example, assume that we have the following declaration:String s = "hello";
The expression
s.charAt(1)
will produce thechar
value'e'
.The expression
s.substring(1, 2)
will produce aString
object for the single-character string"e"
. -
Can I concatenate two
char
values together to get a two-character string?No! Because
char
s are stored as numeric character codes, adding them will produce an integer, not a string.For example, assume that we have the following declaration:
String school = "Boston University";
the expression
school.charAt(0) + school.charAt(7)
will evaluate to:
151
because
151
is the sum of the character codes for'B'
and'U'
.To fix this, you can include an empty string between the two
char
s. For example:school.charAt(0) + "" + school.charAt(7)
will evaluate to:
"BU"
This works because as long as at least one of the two operands of the
+
operator is a string, Java will convert the other operand to a string as needed so that it can perform string concatenation. -
In one of my methods for Task 1 of Part II, I’m getting a
StringIndexOutOfBoundsException
. What am I doing wrong?Don’t forget that the characters in a string have index values that go from 0 to length - 1. The exception means that your code is using an index from outside that range.
-
In Task 3 of Part II, my
processGuess
method returns the correct boolean value (true
orfalse
) when I test it in myTester
class, but when I test it in the context of the larger program, it always returnsfalse
. Why might this be happening?One possible explanation is that you may be trying to compare strings using the == operator. This won’t work, because strings are objects, and the
==
operator only compares the memory addresses of objects. To compare the internals of two objects, you need to use a method (theequals
method) to compare them.Using
==
can work when you test your method from yourTester
class if your test calls are using string literals. For example, imagine that we have the following test call:boolean result = Wordle.processGuess("edict", "edict");
Because we have two literals for the same word, the Java interpreter uses a single
String
object for both of them. As a result, both parameters ofprocessGuess
end up referring to the same object:+-----------------+ | +-----+ | | guess | ------------>[ String object for "edict" ] | +-----+ | ^ | | / | +-----+ | / | mystery | ----------/ | +-----+ | +-----------------+
And when we use
==
to compareguess
andmystery
in this case, we get a value oftrue
because both variables hold the same memory address.However, when you call
processGuess
from yourWordle
program, the strings involved are not string literals that you are hard-coding into your program. Rather, one of the strings (the mystery word) is obtained from theWordList
that we have provided. The other string (the guess) is obtained from the user. As a result, even if the two strings happen to represent the same word, there are two separateString
objects in memory:+-----------------+ | +-----+ | | guess | ------------>[ String object for "edict" ] | +-----+ | | | | +-----+ | | mystery | ------------>[ String object for "edict" ] | +-----+ | +-----------------+
And when we use
==
to compareguess
andmystery
in this case, we get a value offalse
because the variables hold two different memory addresses.In order to test if two strings are equivalent, we need to use the
equals
method instead of==
, since it will compare the internals of the two strings. -
Part of my program doesn’t do what it’s supposed to do, and I can’t figure out why. Any suggestions?
You need to perform some debugging! In other words, you need to step through your program to see how the values of your variables are changing and where your logic errors are.
There are at least two ways to do this:
- Add temporary println statements at various points in the problematic piece of code (e.g., inside each loop). Use these println statements to print the values of the key variables so that you can see how they change over time. Note that you can also print out the value of an expression (e.g., val < 100) to see how it changes over time.
- Step through the problematic code “on paper”. Make a table for the key variables, and use it to keep track of their values (as well as any outputs) as you “execute” the statements in the same order that the interpreter would use.
-
When I try to run my code, I get an error saying that it can’t find one of the other classes – something that looks like this:
Exception in thread "main" java.lang.NoClassDefFoundError: WordList
Why is this happening?
This probably means that you haven’t properly followed the instructions in the Getting started section at the beginning of Part II.
In particular, make sure that all of the files are in the same folder, and that you use the File->Open Folder menu option in VS Code to open the folder containing your files. Note that you MUST open the folder and not just open the individual files.
To make sure things are correctly configured, we recommend that you do the following:
-
Use File->Close Folder or File->Close Editor to close any open files in VS Code.
-
Shut down the VS Code program.
-
Make sure that all of your files are in the same folder.
-
Start up VS Code again.
-
Use File->Open Folder to open the folder containing your files.
-
As needed, click on the name of the file that you want to edit from the list of files in the Explorer Pane on the left-hand side of VS Code.
Some other things to check:
-
Make sure that your files do NOT include a package statement at the top. For example, if you see something like this:
package ps2; // remove this!
at the top of a file, you should remove it.
-
Make sure that the only
import
statements at the top of your file are forjava.util.*
. All otherimport
statements should be removed.
-
-
When I submit my code on Gradescope, it tells me that I’m failing a test for Task 4 because the program throws an exception of type
java.util.NoSuchElementException
from within aScanner
method that is being called byreadGuess
. Why is this happening?This probably means that your
main
method is doing one or both of the following:-
making too many calls to
readGuess
. Once the user has guessed the mystery word, you should NOT continue to callreadGuess
. -
closing the
Scanner
object (the one that we create at the start ofmain
and pass intoreadGuess
) too soon. It should only be closed at the very end of the program, after all calls toreadGuess
have been made.
-
-
For Task 4, I have written a loop that performs 6 repetitions. How can I end the loop early if the user guesses the mystery word in fewer than 6 guesses?
One option is to use a
break
statement to break out of the loop early when the user guesses the mystery word.Another option is to use an indefinite loop (e.g., a
while
loop) whose condition includes aboolean
variable that keeps track of whether the user has guessed the mystery word. -
Sometimes when I run the program, the program behaves unexpectedly – e.g., telling me that my guess is invalid before I even enter a guess, or repeatedly asking for a new guess without giving me the chance to enter anything. Why is this happening?
This can happen if you try to run the program when you are still in the middle of a previous run. Either complete that previous run or use Ctrl-C to end it. Then, once the previous run is completed, you should be able to start a new run of the program and have it behave as expected.
-
I’m using the random-seed option for testing that you suggest at the end of Task 4. After performing a given run, I realized that I needed to make some changes to my code. However, after I made those changes and tried to rerun the program using the same random seed, the program didn’t seem to take into account the changes that I made to the code. Why is this happening.
The process of using a random seed requires that you enter two separate commands from the Terminal. First, you must compile your code:
javac Wordle.java
Then, you enter a second command to run the program with a particular random seed. For example, to use a random seed of 10, you would do:
java Wordle 10
After you make any changes to your code, you must reenter both of these commands from the Terminal to compile your modified code and run it. If you only enter the second command (the one needed to run the program), you will still be running the old version of your code!
-
In Task 5, I’m having trouble getting
processGuess
to handle all of the possible cases. Any suggestions?This is a challenging problem, and you shouldn’t worry if you can’t get it to work correctly in all cases.
Try tracing through concrete cases on paper and think about how you can tell whether a given character that isn’t in the correct position is truly needed elsewhere to form the mystery word. Taking advantage of one or more of the helper methods that you wrote in Task 1 should help with this.
One important thing to check: Make sure that any changes that you make as part of Task 5 don’t cause your
processGuess
method to fail the simpler test cases from Task 3 that the original version ofprocessGuess
was designed to handle! Task 3 is worth more points than Task 5, so it’s more important that you are able to correctly handle those test cases.