Karly
Karly

Reputation: 41

Calculating check out price

For this program we are supposed to calculate the total price of items entered by the user. We are using methods for getting a ranged double and a method that asks the user if they want to continue. Here are the methods I am using:

public static double getRangedDouble(Scanner src, String prompt, double lo, double hi)
    {
        double retVal = lo - 1;
        String trash;
        do
        {
            System.out.print(prompt + " " + lo + " - " + hi);
            if(src.hasNextInt())
            {
                retVal = src.nextInt();
            }
            else
            {
                trash = src.nextLine();
            }
        }while(retVal < lo || retVal > hi);

        return retVal;
    }

    public static Boolean getYNConfirm(Scanner src, String prompt)
    {
        String input = "";
        boolean done=true;

        System.out.println(prompt + " Y or N");
        while(!done)
        {
            input = src.nextLine();
            if(input.equalsIgnoreCase("Y"))
            {
                done=true;
            }
            else if(input.equalsIgnoreCase("N"))
            {
                done=false;
            }
            else
            {
                System.out.println("Y or N");
            }
        }
        return done;
    }

And here is the description straight from my assignment:

At the 10$ store nothing is more than $10.00. Prompt the user for the price of their item (.50 cents to $9.99 dollars) using the getRangedDouble method and continue to input items as long as they indicate that they have more using your getYNConfirm method. Display the total cost of the item(s) to 2 decimal places with printf.

I know how to use the methods in the program but I have no idea how to get the getYNConfirm method to work or how to calculate the total price as the user enters the separate prices. Any help would be greatly appreciated.

Upvotes: 3

Views: 2500

Answers (3)

Mshnik
Mshnik

Reputation: 7042

Alrighty, so let's jump into your question:

At the 10$ store nothing is more than $10.00. Prompt the user for the price of their item (.50 cents to $9.99 dollars) using the getRangedDouble method and continue to input items as long as they indicate that they have more using your getYNConfirm method. Display the total cost of the item(s) to 2 decimal places with printf.

The first big thing to do with just about any coding question at this level is break it up into its constituent parts. For this question, those are:

  1. Be able to ask the user for the price of an item (check)
  2. Be able to ask the user if they have another item to enter (check-ish... see below)
  3. Loop the above 2 steps as long as the second is true (TODO)
  4. Be able to sum the values given in each price step of the loop (TODO)

For step 1, we have the getRangedDouble(...), which checks out. Here it is copied for convenience:

public static double getRangedDouble(Scanner src, String prompt, double lo, double hi){
  double retVal = lo - 1;
  String trash;
  do{
    System.out.print(prompt + " " + lo + " - " + hi);
    if(src.hasNextInt()){
       retVal = src.nextInt();
    } else {
       trash = src.nextLine();
    }
  } while(retVal < lo || retVal > hi);
  return retVal;
}

For step 2, we have the getYNConfirm(...) method, given here:

public static Boolean getYNConfirm(Scanner src, String prompt){
  String input = "";
  boolean done=true;
  System.out.println(prompt + " Y or N");
  while(!done){
    input = src.nextLine();
    if(input.equalsIgnoreCase("Y")){
      done=true;
    } else if(input.equalsIgnoreCase("N")) {
      done=false;
    } else {
      System.out.println("Y or N");
    }
  }
  return done;
}

Unfortunately, this has a logical bug in it. You initialized done to true, and your while loop is over the condition while(!done). Thus the first time this is while(!true) --> while(false), which doesn't execute. So the while loop will never be entered, thus we return true every time you call the method. To fix this, consider what you do once you see a "Y" - you eventually return true. Your method goes through the motions of breaking the loop first, but we could just skip that step and jump straight to returning true. Thus consider this version of the getYN... method:

public static boolean getYNConfirm(Scanner src, String prompt){
  String input = "";
  System.out.println(prompt + " Y or N");
  while(true){ //Loops forever until a return or break statement 
    input = src.nextLine();
     if(input.equalsIgnoreCase("Y")){
       return true;
     } else if(input.equalsIgnoreCase("N")) {
       return false;
     } else {
       System.out.println("Y or N");
     }
   }
}

This matches the intention of your original version of the method, without the logical bug.

So now we are on to our big finale - write a method using the above two methods as helpers that loops and continually asks the user for more prices, summing as it goes. Let's write this method as main(String[] args), just so we can run it and see what happens.

We want to use a loop here, in order to allow the user to continue to input prices until they are done. We can model our problem with psuedocode as follows:

while(user not done inputting prices){
    get next price
    add price to sum of prices
    ask the user if they would like to continue
}
print sum of prices

Just like you can call a built in method and store the results of the output such as rentVal = src.nextInt(), you can do the same with methods you've written. For example, we can ask for the user to input the next price with getRangedDouble(...). By the method header we wrote, this returns a value of type double, so when we store the output of this call it should be in a double variable: double nextPrice = getRangedDouble(...);

If the psuedocode makes sense, the code that follows is actually relatively simple:

public static void main(String[] args){

  Scanner s = new Scanner(System.in); //Allow for reading user input from console

  boolean looping = true; //True so long as the user isn't done inputting prices.
                          //Initially true so that at least one price is entered
  double sum = 0.0;       //The sum of prices thus far
  while(looping){
    double nextPrice = getRangedDouble(s, "Enter a price in the range", 0.5, 10.0);
    sum = sum + nextPrice; //Add the price into the sum
    looping = getYNConfirm(s, "Add another item to your cart?");
  }
  System.out.println(String.format("%.2f", sum)); //Prints sum, limited to 2 decimal places
}

Upvotes: 1

krisdestruction
krisdestruction

Reputation: 1960

I don't see why this is an invalid answer. I feel the code is very self explanatory here. I added some additional reasoning but I'm glad to explain if there's anything wrong with it

So the code is as follows.

public static double getRangedDouble(Scanner src, String prompt, double lo, double hi)
{
    boolean valid = false;
    while( !valid ) {
        System.out.print(prompt + " " + lo + " - " + hi);
        if(src.hasNextInt())
            retVal = src.nextInt();
        else
            src.nextLine();

        if( retVal < 10 && retVal > 0.5 )
            valid = true;
    }

    return retVal;
}

public static Boolean getYNConfirm(Scanner src, String prompt)
{
    String input;
    boolean done = false;
    double total;
    DecimalFormat df=new DecimalFormat("#.##");

    while(!done) {
        System.out.println("Y or N");
        input = src.nextLine();

        if(input.equalsIgnoreCase("Y"))
            done=true;
        else if(input.equalsIgnoreCase("N")) {
            done=false;
            total += getRangedDouble( file, "Specify the price between:", 0.50, 9.99);
            System.out.println( "The total is:" + df.format( total ) );
        }
    }
    return done;
}

Essentially you want to call getRangedDouble to ask the user to specify the price. You do that by adding the return total += getRangedDouble

The parameters you want to feed are the Scanner, prompt, low, and high limits.

( file, "Specify the price between:", 0.50, 9.99);

In getRangedDouble, you want to get the user input while the response is not valid. So you were right, just keep reading until there's a next good hint.

Afterwards get and check their price input until you get the desired price range.

retVal < 10 && retVal > 0.5

When that happens, it's valid. Set the value to true, and return retVal. To format the total, all you need to do is use DecimalFormat. This line creates the decimal formate with #.## specifying a 2 decimal place precision.

DecimalFormat df=new DecimalFormat("#.##");

then you can call df.format( total ) to format your total while printing it.

Upvotes: 1

Makoto
Makoto

Reputation: 106518

I only see one usage of your getYNConfirm method (which is strange), but there's a rather subtle logic bug buried in it.

Observe:

while(!done)

If done is true, then the expression above reads:

while(false)

...which indicates that this loop will never be executed.

From what you've shown us thus far, the solution is as simple as converting the initial state of done to false:

boolean done = false;

As an aside, generally you want to return the boxed types for primitives when you absolutely must. In this scenario, I wouldn't see any value in you returning a Boolean as opposed to boolean.

Upvotes: 0

Related Questions