Friday, September 23, 2011

Arithmatic Tutor, updated with variable congrats messages

Problem: "To add variety to the interaction, modify your solution to exercise 5 so that it randomly chooses among four or five different messages when the student gets the right answer."

What it looks like:


The code was all the same except that instead of printing the hard-coded string "Right" if the user got the answer right, it printed answerAffirmation. This was a method that generated one of 4 random integers and mapped each integer to a different congrats message.

 if (userAnswer == programSolution) {
     println(answerAffirmation());
 }
 else {
     println("No, the correct answer is " + programSolution); 
 }

I used a switch statement. At first the method was buggy because the program thought I wasn't returning a result:

The problem was, even though having the strings map to one of four integers that I knew would be exhaustive, the program didn't realize that answers could only come from that random integer, so I must include a default string to get returned:

In reality the message "Grrrrreat!" won't get returned unless there's a bug with my method loops or with the rgen factory resource.


3 comments:

  1. Ah, this problem with switch statements actually shows up in the textbook, for an example method for the "Stoplight" class called getState();

    /**
    * Returns the current state of the stoplight.
    * @return The state of the stoplight (GREEN, YELLOW, or RED)
    */
    public Color getState() {
    switch (state) {
    case 0: return GREEN;
    case 1: return YELLOW;
    case 2: return RED;
    default: return null; /* Can't occur but required by Java */
    }
    }

    ReplyDelete
  2. You could also consider defining a list of affirmations and then picking one randomly, for e.g.:

    // In your constructor
    this.affirmations = new ArrayList();
    this.affirmations.add("That's it!");
    this.affirmations.add("Hi five, that's the correct answer!");
    // ...

    Then you can rewrite like so:

    public String randomlyChoose(List elements) {
    int index = rgen.nextInt(0, elements.size() - 1);
    return elements.get(index);
    }

    // ...

    if (userAnswer == programSolution) {
    println(randomlyChoose(this.affirmations));
    }
    else {
    println("No, the correct answer is " + programSolution);
    }

    Why might this be preferred? Here are some reasons, some disputable some not:

    - Avoids the unnecessary use of default in the switch
    - Separates your data (i.e. possible affirmations) from business logic (i.e. how to choose affirmations)
    - Creates a general method for randomly choosing from a list of String objects, might be useful later
    - Possible that testing randomlyChoose() is easier than testing answerAffirmation()

    ReplyDelete
  3. Or even just an Array literal instead of a case statement. That'd be groovy too.

    ReplyDelete