CS 112
Spring 2022

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.

  1. In the material about String objects in Problem 2, you mention that we need to use an equals method to compare two String objects to see if they are equivalent. What about comparisons of char values?

    char values are primitives, so they are compared using the == operator.

  2. I’m constructing one of the expressions for Problem 2, and I need to convert a single character to its uppercase equivalent. However, because chars are primitives, they don’t have a toUpperCase method. What can I do?

    Instead of using charAt to get a char for the single character, use substring to get a String object of length 1. For example, assume that we have the following declaration:

    String s = "hello";
    

    The expression s.charAt(1) will produce the char value 'e'.

    The expression s.substring(1, 2) will produce a String object for the single-character string "e".

  3. Can I concatenate two char values together to get a two-character string?

    No! Because chars 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 chars. 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.

  4. 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.

  5. In Task 3 of Part II, my processGuess method returns the correct boolean value (true or false) when I test it in my Tester class, but when I test it in the context of the larger program, it always returns false. 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 (the equals method) to compare them.

    Using == can work when you test your method from your Tester 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 of processGuess end up referring to the same object:

    +-----------------+
    |         +-----+ | 
    | guess   |  ------------>[ String object for "edict" ]
    |         +-----+ |       ^
    |                 |      /
    |         +-----+ |     /
    | mystery |  ----------/
    |         +-----+ |
    +-----------------+
    

    And when we use == to compare guess and mystery in this case, we get a value of true because both variables hold the same memory address.

    However, when you call processGuess from your Wordle 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 the WordList 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 separate String objects in memory:

    +-----------------+
    |         +-----+ | 
    | guess   |  ------------>[ String object for "edict" ]
    |         +-----+ |       
    |                 |      
    |         +-----+ |     
    | mystery |  ------------>[ String object for "edict" ]
    |         +-----+ |
    +-----------------+
    

    And when we use == to compare guess and mystery in this case, we get a value of false 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.

  6. 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:

    1. 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.
    2. 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.
  7. 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:

    1. Use File->Close Folder or File->Close Editor to close any open files in VS Code.

    2. Shut down the VS Code program.

    3. Make sure that all of your files are in the same folder.

    4. Start up VS Code again.

    5. Use File->Open Folder to open the folder containing your files.

    6. 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 for java.util.*. All other import statements should be removed.

  8. 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 a Scanner method that is being called by readGuess. 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 call readGuess.

    • closing the Scanner object (the one that we create at the start of main and pass into readGuess) too soon. It should only be closed at the very end of the program, after all calls to readGuess have been made.

  9. 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 a boolean variable that keeps track of whether the user has guessed the mystery word.

  10. 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.

  11. 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!

  12. 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 of processGuess 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.