Reputation: 41
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
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:
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
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
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