Birthday money calculator - java

My assignment is to create a calculator that can calculate how much is left on a giftcard after purchasing an item, but also making sure not to go over 6 items, or $225, whichever comes first. I know I need another method to do a calculation but i'm not sure what to put in it. This is what I have so far:
I know I will need a for loop for the counter for the items, but I'm really stuck. I posted the actual assignment to give background.
For your birthday, your rich aunt & uncle give you a $225 gift card to
the local mall. They will go shopping with you and will help carry out
your items. The most that each of you can carry is one item in each
hand. Thus, you may purchase a maximum of six items. You will have a
tracker device that computes the number of items you purchase as well
as the amount of money you have spent. After you choose each item, the
tracker prompts you for the price, and then displays the amount of
money you have spent. Then it displays the number of items you may
still choose and the balance on the gift card. The program will not
terminate until you reach 6 items or $225, whichever comes first. The
tracker then will list the total spent & the number of items as well
as the balance on the gift card.
Required:
validate that negative
prices are not entered and that you can’t spend more than the balance
on the gift card. Give the user as many opportunities as needed to
enter a price above 0 or below 225. User should be able to purchase
items costing between one penny and $225, inclusive.
all dollar
amounts should be formatted for currency using the NumberFormat class.
Include at least 1 method in your program.
Be sure to create test cases for all options:
spend the entire dollar amount on fewer than 6 items
purchase 6 items totaling less than the entire dollar amount
spend the entire dollar amount on exactly 6 items
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double priceItem = 0, totalPrice = 225, currentPrice = 0;
int numItem;
System.out.println("Happy birthday from Auntie and Uncle! \nYou may purchase up to"
+ " 6 items with this gift card of $225.");
for (numItem = 1; numItem <= 6; numItem++) {
System.out.println("Enter the price for item #" + numItem + ": ");
priceItem = input.nextDouble();
while (numItem <= 6 && totalPrice <= 225) {
totalPrice = currentPrice - priceItem;
System.out.println("You may buy this item. You have spent ");
if (currentPrice > totalPrice) {
System.out.println("Item is too expensive. Balance on gift card is " + currentPrice);
}
}
}
}
Whenever I have tried to make a while loop, it is an infinite loop and again I'm not sure which calculation to put in to get it to break.

I don't want to give you the answer as it is something you should solve yourself but I will give a few pointers.
Your use of a while loop here is incorrect, do you really need a while loop?
if(totalPrice <= 225) break;
Perhaps look into the break statement to exit the loop when a certain condition is met, that why you can ensure there are 6 items or less and it is not over 225.
You also need to handle an entry of 0 as it is a penny minimum and you cannot allow them to exceed 225.
priceItem = input.nextDouble();
while(priceItem < 0.01 || priceItem > 225){
System.out.println("Item Price cannot be 0 or greater than 225, please...");
priceItem = input.nextDouble();
}
You also can't allow a value that exceeds the remaining balance, I will let you try and figure out how to do that yourself. What you have done so far isn't bad you just need to break it down a bit more.

This is how I would construct it:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double balance = 225.0;
double itemPrice = 0;
int boughtItems = 0;
int maxItems = 6;
System.out.println("Happy birthday from Auntie and Uncle! \nYou may purchase up to"
+ " 6 items with this gift card of $225.");
while(boughtItems < maxItems && balance > 0) {
System.out.print("You have " + balance + "$ on your giftcard. \nEnter the price for item #" + (boughtItems + 1) + ": ");
itemPrice = input.nextDouble();
if(balance - itemPrice > 0.0) {
balance -= itemPrice;
System.out.println("You have bought the Item!\n\n\nYou can carry " + (maxItems - boughtItems - 1) + " more things!\n");
boughtItems++;
} else {
if(balance - itemPrice == 0) {
balance -= itemPrice;
boughtItems++;
System.out.println("\nYou have spent all your money.");
}
else {
System.out.println("You dont have enough money for this Item!\n\n\n");
}
}
}
System.out.println("You bought " + boughtItems + " item/s. " + "Have fun with the stuff!");
}
You can write a buy(double balance, double price) method for example, so you fill in the assignment requirements.
And of course you need to do the rest of the stuff like the number-formatting.

In the while loop, you are doing wrong assignment, that’s why infinite loop.
Assign currentPrice is equal to totalPrice - price for item purchased.

Related

Why does the code print the statement twice, but differently?

My problem statement is:
Write a program that creates two instances of the generic class
LinkedList.
The first instance is stadiumNames and will hold items of
type String.
The second instance is gameRevenue and will hold items of
type Double.
Within a loop, read data for the ball games played during
a season.
The data for a game consists of a stadium name and the
amount of money made for that game.
Add the game data to stadiumNames and gameRevenue.
Since more than one game could be played at a particular stadium, stadiumNames might have duplicate entries.
After reading the data for all of the games, read a stadium name and display the total amount of money made for all the games at that stadium.
I'm trying to get each input from the user and then add each input together and get its sum, it seems to get it right at first, but then it prints another totally different amount. Why is that? Any help appreciated.
Each input the stadiumName and gameRevenue were added to a linkedList.
Note that I already wrote both linked lists but it won't allow me to post a big chunk of code. Thank you.
boolean Data = true;
while (Data) {
stadiumNames.add(name);
gameRevenue.add(rev);
System.out.println("Do you want another game? ");
String yesorno = scan.next();
if (yesorno.equals("No"))
break;
else {
if (yesorno.equals("yes"))
System.out.println("Enter stadium name: ");
name = scan.next();
System.out.println("Enter amount of money for the game: ");
rev = scan.nextDouble();
for (int i = 0; i < stadiumNames.size(); i++) {
if (stadiumNames.get(i).equals(name)) {
rev += gameRevenue.get(i);
System.out.println("The total amount of money for " + name + " is " + rev);
}
}
}
}
If you want to print running total while user is entering the data, total should be reset for each calculation.
while (true) {
System.out.println("Do you want another game? ");
String yesorno = scan.next();
if (yesorno.equals("No"))
break; // else not needed
System.out.println("Enter stadium name: ");
name = scan.next();
System.out.println("Enter amount of money for the game: ");
rev = scan.nextDouble();
stadiumNames.add(name);
gameRevenue.add(rev);
double total = 0.0;
// recalculating the total for the last stadium
for (int i = 0; i < stadiumNames.size(); i++) {
if (stadiumNames.get(i).equals(name)) {
total += gameRevenue.get(i);
}
}
System.out.println("The total amount of money for " + name + " is " + total);
}
However, it may be needed to calculate the totals for multiple different stadiums and a map needs to be created and filled for this after the while loop.
It is convenient to use Map::merge function to accumulate the totals per stadium name.
Map<String, Double> totals = new LinkedHashMap<>();
for (int i = 0; i < stadiumNames.size(); i++) {
totals.merge(stadiumNames.get(i), gameRevenue.get(i), Double::sum);
}
totals.forEach((stad, sum) -> System.out.println("The total amount of money for " + stad + " is " + sum));
Aside comment: it is not recommended to use double for financial calculations because floating point maths is not precise.

Updated Variable in a While Loop

I have this while loop that runs as a user input fee is larger then a transaction amount. For example, if the fee is $4 and you only pay $2, it will say you still owe $2 and prompt you to enter more payments. The problem is that I cannot figure out how to update the variable transaction after a payment if it is still short. After it asks for another payment, say you are still short of the $4 and pay another $1, that will give you a total of $3 and the program should say you are still short by $1. Nonetheless, the program still says you are short by the original amount, i.e. $2.
while (transaction < feeSum)
{
double underPay = feeSum - transaction;
System.out.println("The transaction did not meet the fee by $" + underPay);
System.out.println("Please enter another payment to complete the balance.");
System.out.println("Enter a number of payments.");
int paymentSize2 = keyboard.nextInt();
double[] payments2 = new double[paymentSize2];
System.out.println("Enter " + payments2.length + " payment(s).");
double paymentSum2 = 0;
for(int i = 0; i < payments2.length; i++)
{
payments2[i] = keyboard.nextDouble();
paymentSum2 = paymentSum2 + payments[i];
transaction += paymentSum2; //<<<<<<< Shouldn't this update transaction?
} // The second time around it should say the trans did not meet fee by $1
if (paymentSum2 == underPay)
{
System.out.println("There is now no outstanding balance.");
break;
}
I remade your code a little, this will work, however it doesn't contain all that extra stuff you implemented. I don't really understand why you need those arrays.
This code doesn't handle if you pay more than you should, however that could easily be implemented in the last lines of the while loop.
double underPay = feeSum - transaction;
while (underPay != 0) {
System.out.println("The transaction did not meet the fee by $" + underPay);
System.out.println("Please enter another payment to complete the balance.");
int paymentSizeNext = keyboard.nextInt();
underPay -= paymentSizeNext;
}
System.out.println("There is now no outstanding balance.");

Do / While Loop Verification

I'm using javax.swing.JOptionPane.
I need the user to enter in the product number, revenue, and expenses.
I need to validate the information to make sure that the revenue is between 0 and 20000 and verify that the expenses are between 1500 and 10000. I need to make sure that if they enter in an invalid revenue or expense it prompts them, and not allow the program to continue.
The program needs to be able to determine if there was a net profit, loss, or break even.
The user has to have the option of entering multiple records. Also, I need to count how many times the user entered in the information.
I feel like I was able to knock out a big chunk of the code.
When the user inputs an invalid revenue or expense, it keeps looping the messages and doesn't return to the ability to enter in the values again.
I also am not sure how I am going to get the user to input "Y" to loop the entire program again.
Can anyone lend me some assistance please?
/**
* The program will output the Product Number, Revenue, Expenses, as well as the Net Income
*/
import javax.swing.JOptionPane;
import java.io.*; // Access System.out
import java.util.Scanner;
public class RevenueJopt
{
public static void main(String[] args)
{
// Declarations
double finalValue;
char repeat;
int counter = 1;
String input;
Scanner keyboard = new Scanner(System.in);
// Do Loop to run
do{
// Advise the user the conditions that have to be met for inputs
JOptionPane.showMessageDialog(null,"Please ensure that your revenue is between 0 to 20,000.00 dollars." +
"\nPlease ensure that your expenses are between 1,500.000 to 10,000.00 dollars.");
// Ask user the values of the variables
String response = JOptionPane.showInputDialog(null, "Enter in a Product Number(or -1 to END)");
String response1 = JOptionPane.showInputDialog(null, "Enter the Revenue?");
String response2 = JOptionPane.showInputDialog(null, "Enter the Expenses?");
// Read in values
int productNumber = Integer.parseInt(response);
float revenue = Float.parseFloat(response1);
float expenses = Float.parseFloat(response2);
//While loop to Validate Information
while(revenue < 0 || revenue > 20000 || expenses < 1500 || expenses > 10000) {
JOptionPane.showMessageDialog(null,"You have entered in either an invalid revenue or expense. Please enter in valid numbers.");
{
JOptionPane.showMessageDialog(null,"Here is the product number you entered: " + productNumber + "."
+ "\nHere is the revenue you entered: " + revenue + "."
+ "\nHere are the expenses you entered: " + expenses + ".");
JOptionPane.showMessageDialog(null,"Enter in a Product Number (or-1 to END)"
+ "\nEnter the Revenue"
+ "\nEnter the Expenses");
//When this part runs, it goes into an infinite cycle. I am not sure how to break free of this.
counter++;
//calculates final value
}
}
finalValue = revenue - expenses;
// Calculates final value and displays as net profit, loss or break even.
if (finalValue > 0) {
JOptionPane.showMessageDialog(null, "You made a profit. Your net income is: "+finalValue);
} else if (finalValue == 0) {
JOptionPane.showMessageDialog(null, "You broke even. Your revenue was "+ revenue +" your expenses were " +expenses);
} else if (finalValue < 0) {
JOptionPane.showMessageDialog(null,"You have not made any profit. Your net loss is: "+finalValue);
}
JOptionPane.showMessageDialog(null,"Number of records: " +counter);
//validate user input
JOptionPane.showMessageDialog(null,"Would you like to input more records?");
String response3 = JOptionPane.showInputDialog(null, "Enter 'Y' for yes or 'N' for no.");
// I am not sure how to hold the value "Y" to make the loop keep repeating
input = keyboard.nextLine();
repeat = input.charAt(0);
counter++;
}
while(repeat == 'Y' || repeat == 'y');
}
}
Replace
input = keyboard.nextLine();
repeat = input.charAt(0);
with
repeat = response3.charAt(0);
to get the first character of the String entered into the input dialog box.
However, this will throw an StringIndexOutOfBoundsException if the user enters nothing into the dialog box, so you have to decide on a default value for that case:
repeat = response3.isEmpty() ? 'n' : response3.charAt(0);
Reading from System.in is basically for CLI applications.
Also check the "validate information" while loop. If the user enters invalid values, he will be informed about this indefinitely, with no chance of entering correct values.

In Java, is it possible to use some sort of while loop (or anything) to determine the amount of prompts for input?

public static void main (String [] args)
{
// declare variables, capture input
String input, name = JOptionPane.showInputDialog("Please " +
"enter your first and last name.");
double testScore1, testScore2, testScore3, average;
// capture input, cast, and validate input
input = JOptionPane.showInputDialog("What is the score " +
"of your first test?");
testScore1 = Double.parseDouble(input);
while (testScore1 < 1 || testScore1 > 100)
{
input = JOptionPane.showInputDialog("This test score is not " +
"between 1 and 100. \nPlease enter a test score in " +
"this range:");
testScore1 = Double.parseDouble(input);
}
input = JOptionPane.showInputDialog("What is the score " +
"of your second test?");
testScore2 = Double.parseDouble(input);
while (testScore2 < 1 || testScore2 > 100)
{
input = JOptionPane.showInputDialog("This test score is not " +
"between 1 and 100. \nPlease enter a test score in " +
"this range:");
testScore2 = Double.parseDouble(input);
}
input = JOptionPane.showInputDialog("What is the score " +
"of your third test?");
testScore3 = Double.parseDouble(input);
while (testScore3 < 1 || testScore3 > 100)
{
input = JOptionPane.showInputDialog("This test score is not " +
"between 1 and 100. \nPlease enter a test score in " +
"this range:");
testScore3 = Double.parseDouble(input);
}
// calculate average and display output
average = (testScore1 + testScore2 + testScore3)/3;
JOptionPane.showMessageDialog(null, name + ", your average score is: " + average);
}
First off, I'm a beginner programmer. My terminology and jargon are quite lacking, so bear with me.
I'm writing a program to capture 3 test scores then validate them using a while loop (must be within the 1-100 range). The test scores are then averaged and the output displays the average. Pretty simple stuff.
I'm wanting to find a way, if possible, to capture the number of test scores, then from there, capture each actual score. For example, the program asks "How many tests are being computed for average?", then take that number and have it be the same amount of times the program prompts, "Please enter test score (1):" or something along those lines. So for further clarity, if the user typed 4 for number of tests, then the prompt for inputting the score would show up 4 times.
I feel the above code is redundant by using a while loop for each score and at that, limited because the program is only meant for 3 scores. Any help is much appreciated and feel free to critique anything else in the code.
Yes you can.
What you need is a nested loop. In pseudo code:
while(condition)
{
int numberOfInput = getInput() ; //get the input from the user
for(int i =0 ; i < numberOfInput; i++) //iterate for the amount of prompts required
prompt() ; //get input
}
function prompt
while (testScore1 < 1 || testScore1 > 100)
{
input = JOptionPane.showInputDialog("This test score is not " +
"between 1 and 100. \nPlease enter a test score in " +
"this range:");
testScore1 = Double.parseDouble(input);
}
Short answer:Yes, it is possible.
Option 1: Initially ask the user how many scores they are planning on entering, and store that in an int variable.
For example:
Ask user how many scores to enter.
Check the response, and store it in an int variable.
Create a double variable to add the scores (initialize it to 0.0)
Use a for loop, asking for the score;
Evaluate the score to ensure it's a valid number
If it's not a valid number, prompt the user again (this is still within
the same iteration, not a different iteration)
If it's a valid number, add it to the total scores variable
Once loop is exhausted, just divide the two variables (since the total
scores is a double, your answer will automatically be a double)
Display the answer.
Option 2: Use a sentinel-loop (the user has to enter a letter -usually 'Q' or 'N'- or something to exit the loop)
Create an int variable to store total loops (initialize to 0).
Create a double variable to add the scores (initialize it to 0.0)
Use a for loop, asking for the score;
Check if the value is the quit character
If it is not
Evaluate the score to ensure it's a valid number
If it's not a valid number, prompt the user again (this is still within
the same iteration, not a different iteration)
If it's a valid number, add it to the total scores variable and increment
the total loops variable by 1.
If it is
just divide the two variables (since the total
scores is a double, your answer will automatically be a double)
Display the answer.
Hope it helps.
In http://korada-sanath.blogspot.in/p/discussion-on-tech-topics.html, there is a pseudo code which illustrates similar problem with basic Java programming skills. In that in looping section you can simply add a check whether user entered score is in range 1-100 or not. If not, you can decrease loop variable by '1' so that user can enter his score one more time...
For further illustration please add below code in looping section of code present in above mentioned link.
instead of directly assigning user entered value to your testScores array, you can use one temp var and then can assign if user entered score in range.
Double temp = Double.parseDouble(br.readLine());
if(temp > 1 && temp < 100) {
testScores[loopVar] = temp;
} else {
loopVar--;
}

Why is this giving me an infinite loop?

I was going through a code used to calculate investments until it has doubled and I received an infinite loop that I can't seem to solve. Can anyone figure out why this is giving me an infinite loop? I've gone through myself but I can't seem to find the problem. The "period" referred is how many times per year the interest is compounded.
double account = 0; //declares the variables to be used
double base = 0;
double interest = 0;
double rate = 0;
double result = 0;
double times = 0;
int years = 0;
int j;
System.out.println("This is a program that calculates interest.");
Scanner kbReader = new Scanner(System.in); //enters in all data
System.out.print("Enter account balance: ");
account = kbReader.nextDouble();
System.out.print("Enter interest rate (as decimal): ");
rate = kbReader.nextDouble();
System.out.println(" " + "Years to double" + " " + "Ending balance");
base = account;
result = account;
for (j=0; j<3; j++){
System.out.print("Enter period: ");
times = kbReader.nextDouble();
while (account < base*2){
interest = account * rate / times;
account = interest + base;
years++;
}
account = (((int)(account * 100))/100.0);
//results
System.out.print(" " + i + " " + account + "\n");
account = result;
}
The code should ask for three "periods", or three different times the entered data is compounded per year (ex annually, monthly, daily etc.)
Thanks a lot!
Instead of doing
account =interest +base
You should have
account = interest +account
You should add some sanity checking. Either check if all the numbers will result in a finite number of loops (account and rate != 0, maybe some other stuff), or more simply, break if you've looped more times than would be reasonable (say 1000 for instance). My guess is that rate is 0 resulting in no increase in account, therefore it will loop forever.
You have a calculation error:
account = interest + base;
Presumably this should be:
account = account + interest;
Also, are you sure you want to have the int cast?
account = (((int)(account * 100))/100.0);
You're throwing away the values smaller than 1 cent apparently. However, if the interest is too small you will not get any change.
The reason it may loop forever is that the double calculation of account is effectively truncated by casting to int, so it may never change if rate is too small and the new value of account isn't made larger by at least 0.005.

Categories