Sunday, January 23, 2011

Predicate Method to Categorize a Yes or No Question (with Monkey Brains program)

Problem: "Write a predicate method "askYesNoQuestion(prompt)" that prints a string "prompt" as a question for the the user and then waits for a response. If the user enters a string "yes" the askYesNoQuestion method should return true. If the user enters a string "no" the askYesNoQuestion method should return false. If the user enters anything else, the method should remind the user that it is seeking a yes-or-no answer and then repeat the question." (Roberts ch 5, problem 7).

This problem was a good illustration of how boolean methods work as part of a larger program. Let's say you want a program to say, "If True, do X, if False, do y," but the mechanics of evaluating a situation to "True" or "False" take multiple steps. If that's the case, then the "if" part would best be handled by a method call.

What it looks like:


/*

* File: YesNoPredicate.java
* Name: Renee
* Section Leader: 
* -----------------
* 
*/

import acm.program.*;

public class YesNoPredicate extends ConsoleProgram {
    public void run() {
        if (askYesOrNoQ ("Do you have monkey brains?")) {
            println ("Have a bananna");
        }
        else println ("Get outta here");
        }
    
    /*This boolean pushes the user to enter a yes or no answer to an arbitrary string (hopefully
    a question) called "prompt." If the user enters anything but yes or no, the method
    will keep looping until the user enters yes or no. If the user enters "yes", the boolean
will return "true." If the user enters "no", the boolean will return "false."*/

    private boolean askYesOrNoQ(String prompt){ 
        String reply = readLine(prompt);
      
        while ((!reply.equals("yes"))&&(!reply.equals("no"))) {
            println("Please enter a yes or no answer.");
            reply = readLine(prompt);
        }
        return (reply.equals("yes"));
    }
}




What made it tough: At first I thought this problem was super-simple, but it stumped me for 30 min before everything clicked. I knew that I wanted the boolean to say, "If the user enters 'yes,' return 'true.' If he enters anything else, return 'false.' Moreover, if the false answer is not 'no', keep re-prompting for a yes-or-no answer." But I wasn't sure how to build that re-prompt into the predicate method and at first built the re-prompt into the run() method, which isn't the proper place because the predicate part is supposed to take care of that.

I was getting close when it looked like this:

/*
    private boolean askYesOrNoQ(String prompt){ 
        String reply = readLine(prompt);
        return (reply.equals("yes"));
        if (!reply.equals("no")) {
            println("Please enter a yes or no answer.");        
        }
but I kept getting an error "Unreachable code." I had the "return true if yes" part come before the "push the user for a yes-or-no answer" part, though it appears you must have the "return" method be the last part of your private method? That makes sense, because if the user entered "gibberish" and we returned "false", the run() method would act upon the "false" without ever getting a yes-or-no answer from the predicate method.

This was also another good illustration of different ways to pass an object to a method. It's interesting that the argument you pass to the method which inspects the user's input isn't the answer itself, but the prompt. You could easily have designed this program so that you print out the prompt as part of the run() method and pass the user input to the private boolean to evaluate it to true or false; I'm trying to think what the merits of each approach are...

2 comments:

  1. Hi Renee,

    Can you think of a way to rewrite your solution with a single call to readLine(prompt) and a single test for reply.equals("yes")? (both inside the loop)

    -- David

    ReplyDelete
  2. Thanks Renee - I was getting very frustrated with this problem because the book does a very poor job explaining predicate methods and what language is required for them then just throws you to the lions with this problem. Reading your code was a huge help.

    ReplyDelete