Storing values not working? - java

I'm using an array for a project to store currency values, as well as a double variable to hold a running total. When I run my code through the loop, the user input is not stored in the array, and nothing is added to the running total. When the user inputs a -1, it is supposed to break the loop and calculate taxes etc, and when a 0 is inputed, the last value is removed from the array. No matter what I do, I cannot get these values into the array, or the running total to work. I am sure what I am doing wrong is something stupid, but I cannot spot it.
for(i = 0; i < priceArray.length; i++) {
System.out.print("\nEnter the price of the item...");
userInput = input.nextDouble();
if(userInput == -1) { // This will break the user out of the loop.
break;
}
else if(userInput == 0.0) {
System.out.println("You entered a zero, removing last price of $" + priceArray[i] + ".");
i--;
runningTotal =- priceArray[i];
}
else if(userInput > 0.0 && userInput < 2999.99) {
priceArray[i] = userInput;
priceArray[i] += runningTotal;
userInput += runningTotal;
System.out.println("You entered $" + userInput + ", total is $" + runningTotal + ".");
}
else {
i--;
System.out.println("Please enter a valid value under $2999.99.");
}// End if.
};// End for

A couple of things are wrong here
1) When you calculate running total you do it incorrectly (you don't calculate it at all):
priceArray[i] = userInput;
priceArray[i] += runningTotal;
userInput += runningTotal;
It should be this:
priceArray[i] = userInput; /* Save the price */
runningTotal += userInput; /* Increment the total */
Now you will have incremented runningTotal and saved the price correctly.
2) When you remove something (entering 0) you also do it wrong. You print the next empty value, which will be zero and then negate instead of subtracting.
i--; /* Step back one step */
System.out.println("You entered a zero, removing last price of $" + priceArray[i] + ".");
runningTotal -= priceArray[i];
i--; /* The for-loop will increment i for us, so we must subtract one extra time */

In the case where you attempt to remove a value rour running total is going to break. runningTotal =- priceArray[i]; is going to set the value to the negative of the value you are trying to remove. You should use -= instead of =-.
In the case where you attempt to add a value you are also messing up the running total.
priceArray[i] = userInput;
priceArray[i] += runningTotal;
userInput += runningTotal;
I'm not sure what you think is happening on these lines. You set the value of the array at the given index to what was input, which is great. Then you override the value by adding the runningTotal to it, which isn't what you want. Then you are overwriting the input value by adding runningTotal to it, which also isn't what you want. You want to set the value within the array, hten add the value to the runningTotal, and that's it.

Related

How can I make this code not return an infinite loop?

I think I have to use String goAgainResponse to make there not be an infinite loop but I don't know what the code for that would look like. I'm supposed to approximate pi by adding 4 - 4/3 + 4/5 - 4/7 + 4/9 etc. adding as many of these terms together as the number that I ask the user to put in.
int term;
int counter = 1;
double piCalc=0.0;
String goAgainResponse = null;
boolean goAgain = false;
Scanner kb = new Scanner(System.in);
/* NOTE you may not declare any additional variables */
do
{
System.out.println("This program will approximate Pi based on the following series:");
System.out.println("4 - 4/3 + 4/5 - 4/7 + 4/9 - ...");
System.out.println("Enter the term number to which you would like to approximate Pi");
term = kb.nextInt();
while(term <= 9)
{
System.out.print("Please enter a number greater than 9:");
term = kb.nextInt();
}
while(term > 9)
{
term += 1;
piCalc = 4/(2 * term - 1);
System.out.print(piCalc);
}
System.out.print("Would you like to try again (yes/no)? ");
}while(goAgain);
while(term <= 9)
{
System.out.print("Please enter a number greater than 9:");
term = kb.nextInt();
}
In this you are saying term should be greater than 9. But your in your second loop condition is term>9 and you are adding values in term, thats why the second loop is infinte
while(term > 9)
{
term += 1;
piCalc = 4/(2 * term - 1);
System.out.print(piCalc);
}
changing the condition of 2nd loop would resolve your problem. OR
consider term+=1 again.
Also as per #Scary Wombat, value of boolean doagain is never set
boolean goAgain = false;
This is never set to anything else, and the loop only loops while it is true

Program to find factors of number using for loops

My teacher has assigned us a mini project of making a program that will find all factors of any user inputted number. I am using a for loop to do so, but the for loop is failing and I can't figure out why.
Here is the relevant code:
System.out.println("Type a number");
Scanner num = new Scanner(System.in);
for (double number = 1; num.nextDouble() % number == 0; number++) {
if (num.nextDouble() % number != 0)
continue;
if (number > num.nextDouble())
break;
System.out.println(number + "is a factor of " + num);
}
I have looked on Stack Overflow to see if there is a relevant question for my problem, and from what I could find it hasn't been brought up before. If someone could point out what I assume to be a logic error, I would be very grateful.
Problems with your code include, but are not necessarily limited to:
It reads input and generally handles numbers as doubles. It doesn't make much sense to talk about factors of non-integers. Instead use Scanner.nextInt() or Scanner.nextLong(), and handle all your numbers via the corresponding integer data type.
It reads a new number from the input every time it wants to examine the number whose factors are being determined. Instead, read the input once, before the loop or in its initialization clause. Store that result in a variable, and access it from there.
The loop condition is unsuitable. It terminates the loop if number exactly divides the input number (subject to the numeric precision of type double), without printing anything. Instead, loop until number exceeds an appropriate threshold (e.g. the value of the input number).
At the end, it prints the string value of the Scanner where it means to print the value of the number that was factored. Instead, print the variable established for holding the number.
Your issue is that you're trying to compare user input to a variable, however you're getting the user input in the declaration of the for loop, hence it waits for nextDouble everytime the loop is executed since it will check if num.nextDouble() % number == 0 is true every loop.
Your code appears 'stuck' but really it's just waiting for you to enter another number.
Implementation in your code
In the example below I put the nextDouble before the for loop so it will only wait for input from the user once.
double userInput = num.nextDouble();
for (double number = 1; userInput % number == 0; number++) {
}
You're doing this a couple times in your code, this is a full example using your code:
System.out.println("Type a number");
Scanner num = new Scanner(System.in);
double userInput = num.nextDouble();
for (double number = 1; userInput % number == 0; number++) {
if (userInput % number != 0) {
continue;
}
if (number > userInput) {
break;
}
System.out.println(number + "is a factor of " + userInput);
}
An alternative
However since you don't actually seem to be doing anything with a double & since your for loop can be way simpler this will also do the job:
int userInput = num.nextInt();
for (int number = 1; number < userInput; number++) {
if (userInput % number == 0) {
System.out.println(number + " is a factor of " + userInput);
}
}

If-else should not have break?

So my professor mentioned that a break in an if/if-else statement is "bad" code.
What exactly does she mean by that? Also how am I able to fix my code that I currently have written, because it does work the way I want it to, it's just now I need to get ride of the break statement.
int sumOne = 1;
int sumTwo = 1;
int sumOneTotal = 0;
int sumTwoTotal = 0;
while(sumOne > 0 || sumTwo > 0){
System.out.print("Enter a number to add to first sum: ");
//The user enters in a value for the first sum.
sumOne = input.nextInt();
/**
* We use an if-else statment to ensure sumOne is never less than or equal to 0.
* If it does it ends the program immediately and totals the sums.
* This is because we only want the user to enter in positive numbers.
*/
if (sumOne <= 0){
break;
}else{
sumOneTotal = sumOneTotal + sumOne;
}
System.out.print("Enter a number to add to second sum: ");
//The user enters in a value for the second sum.
sumTwo = input.nextInt();
/**
* We use an if-else statment to ensure sumTwo is never less than or equal to 0.
* If it does it ends the program immediately and totals the sums.
* This is because we only want the user to enter in positive numbers.
*/
if (sumTwo <= 0){
break;
}else{
sumTwoTotal = sumTwoTotal + sumTwo;
}
}
//We print out the total of sumOneTotal and sumTwoTotal.
System.out.printf("%1s%1d%12s%1s%1d", "First sum: ", sumOneTotal, " ", "Second sum: ", sumTwoTotal);
Essentially I want the user to enter ANY positive number and that number is added to the first or second sum. Once the user enters any number <= 0 I want the program to stop immediately. The issue that I keep having when I tinker with the code is that the code keeps running through. Meaning if I have the user enter in 0 to be added to the first sum, the code still asks the user to enter in a number for the second sum. I need it to stop right away and not continue. Any help would be a great help! I am using Java.
EDIT!!! So let's say hypothetically I want to make a program that does the exact same thing I am doing now just with no break statement. How would I do so? A few rules. The most outer statement must be a "while" loop. The inner workings of it can be anything. I also need the machine to print out "Enter a number to add to first sum:" and "Enter a number to add to second sum:" alternating. So if I entered in 1,2,3,4. The first sum would be 4 and the second sum would be 6. Last rule is that it can not contain any break statements!
This is a throwback to when structured programming was a new thing, back when goto statements and the like were everywhere. In theory, Ideally, you should never have to use breaks/continues, and only have a single point of return. In reality, doing so can make your job a lot harder by making programs harder to write, harder to read, and take up more computing resources. Multiple returns, continues and breaks are middle men between truly structured programming and spaghetti code. Used properly, there is nothing wrong with them.
Generally, I've found that they will only obscure your code if you're already using bad practices that make your code hard to read (For example, writing huge blocks of logic without breaking it up, tightly coupling objects etc).
If you're interested, here is a link to an interesting perspective on why NOT to use them. And here is a perspective on why they are benefical.
Many others have already answered with code, but here is my shot :)
public class Main {
public static void main(String args[]) {
int sumOne = 1;
int sumTwo = 1;
int sumOneTotal = 0;
int sumTwoTotal = 0;
Scanner input = new Scanner(System.in);
while(sumOne > 0 || sumTwo > 0){
System.out.print("Enter a number to add to first sum: ");
sumOne = input.nextInt();
if (is_positive(sumOne)){
sumOneTotal = sum_numbers(sumOneTotal, sumOne);
System.out.print("Enter a number to add to second sum: ");
sumTwo = input.nextInt();
if(is_positive(sumTwo)){
sumTwoTotal = sum_numbers(sumTwoTotal, sumTwo);
}
}
}
System.out.printf("%1s%1d%12s%1s%1d", "First sum: ", sumOneTotal, " ", "Second sum: ", sumTwoTotal);
return;
}
public static int sum_numbers(int x, int y){
int total = x + y;
return total;
}
public static boolean is_positive(int x){
boolean is_pos = true;
if(x < 0){
is_pos = false;
}
return is_pos;
}
}
I'd say it's now harder to read. The more to the right my code starts to gravitate, the more I feel sorry for who needs to maintain it.. of course, I could remove a level or two of indentation by wrapping (more) bits in methods. Then it becomes easier to read, but there's a point where black-boxing every tiny bit of logic just seems redundant...
If you draw the flowchart of your code you can see it exits a bucle in the middle of it, which isn't right, the right way is for it to exit when evaluated on the while, also when someone is reading your code they should expect the bucle is left when evaluated false on the while not in a random if inside the while block, I took your code and made some fixes to make it work as expected but I'm not sure if that's what your teacher expects.
int sumOne = 1;
int sumTwo = 1;
int sumOneTotal = 0;
int sumTwoTotal = 0;
while (sumOne > 0 && sumTwo > 0) {
System.out.print("Enter a number to add to first sum: ");
// The user enters in a value for the first sum.
sumOne = input.nextInt();
/**
* We use an if-else statment to ensure sumOne is never less than or
* equal to 0. If it does it ends the program immediately and totals
* the sums. This is because we only want the user to enter in
* positive numbers.
*/
if (sumOne > 0) {
sumOneTotal = sumOneTotal + sumOne;
System.out.print("Enter a number to add to second sum: ");
// The user enters in a value for the second sum.
sumTwo = input.nextInt();
/**
* We use an if-else statment to ensure sumTwo is never less
* than or equal to 0. If it does it ends the program
* immediately and totals the sums. This is because we only want
* the user to enter in positive numbers.
*/
if (sumTwo > 0) {
sumTwoTotal = sumTwoTotal + sumTwo;
}
}
}
Much cleaner, no breaks.
int candidate = 0;
int [] sums = {0,0};
int index = 1;
System.out.print("Enter a number to add to first sum: ");
while((candidate = input.nextInt()) > 0){
sums[index] = sums[index] + candidate;
index = (index + 1)%2;
System.out.print("Enter a number to add to " + ((index == 0) ? "first":"second" ) + " sum: ");
}
//We print out the totals.
System.out.printf("%1s%1d%12s%1s%1d", "First sum: ", sums[0], " ", "Second sum: ", sums[1]);
That isn't to say you should always avoid breaks, but in this case you can avoid it to make your code shorter, less redundant.
Sometimes avoiding break is worse than using it. I would write it like this with one less break.
int sumOneTotal = 0;
int sumTwoTotal = 0;
while (true) {
System.out.print("Enter a number to add to first sum: ");
//The user enters in a value for the first sum.
int sumOne = input.nextInt();
if (sumOne <= 0)
break;
sumOneTotal += sumOne;
System.out.print("Enter a number to add to second sum: ");
//The user enters in a value for the second sum.
int sumTwo = input.nextInt();
if (sumTwo <= 0)
break;
sumTwoTotal += sumTwo;
}
You can avoid break but this doesn't make the code clearer/simpler IMHO.
int sumOneTotal = 0;
int sumTwoTotal = 0;
boolean okay = true;
do {
System.out.print("Enter a number to add to first sum: ");
//The user enters in a value for the first sum.
int sumOne = input.nextInt();
if (sumOne <= 0) {
okay = false;
} else {
sumOneTotal += sumOne;
System.out.print("Enter a number to add to second sum: ");
//The user enters in a value for the second sum.
int sumTwo = input.nextInt();
if (sumTwo <= 0) {
okay = false;
} else {
sumTwoTotal += sumTwo;
}
} while (okay);
The same advice applies to using labels. Avoid them where possible unless avoiding them means doing something worse.
while (sumOne > 0 && sumTwo > 0) {
System.out.print("Enter a number to add to first sum: ");
sumOne = input.nextInt();
if (sumOne > 0) {
sumOneTotal = sumOneTotal + sumOne;
System.out.print("Enter a number to add to second sum: ");
sumTwo = input.nextInt();
if (sumTwo > 0)
sumTwoTotal = sumTwoTotal + sumTwo;
}
}
but i agree with others - there is no any sense to avoid "break"
I don't necissarially agree that it is always bad practice to use a break inside an if. However, that is more a matter of opinion than anything, and is not really on topic here. I will answer the part of your question that is on topic, namely: how can I fix my code to not use break inside an if.
The code below will continue to loop, asking a user for input, until they input a valid number. This avoids your original problem and has the added benefit of allowing the user a chance to enter a new number if they make a mistake, instead of exiting the loop and making them start over.
int sumOne = 1;
int sumTwo = 1;
int sumOneTotal = 0;
int sumTwoTotal = 0;
while(sumOne > 0 || sumTwo > 0){
do {
System.out.print("Enter a number to add to first sum: ");
//The user enters in a value for the first sum.
sumOne = input.nextInt();
System.out.print("Enter a number to add to second sum: ");
//The user enters in a value for the second sum.
sumTwo = input.nextInt();
}while(sumTwo <= 0 || sumOne <= 0);
sumOneTotal = sumOneTotal + sumOne;
sumTwoTotal = sumTwoTotal + sumTwo;
}
//We print out the total of sumOneTotal and sumTwoTotal.
System.out.printf("%1s%1d%12s%1s%1d", "First sum: ", sumOneTotal, " ", "Second sum: ", sumTwoTotal);

Java averaging calculator with defined number of entries

I've seen several average calculators but none with this specific function.
Basically, I want it to ask "How many numbers would you like to average?" then "Enter your number" and continue to prompt "Enter your number" after each entry until the "How many numbers..." quantity is fulfilled. I know it's a count-loop (sorry if my jargon is off...I'm only in my second semester of computer programming) but I don't know how to set it up. Thanks in advance for your answers. Here's what I have so far:
import java.util.Scanner;
public class TestScoreApp
{
public static void main(String[] args)
{
// welcome the user to the program
System.out.println("Welcome to the Test Average Calculator!");
System.out.println(); // print a blank line
// display operational messages
System.out.println("Please enter test scores that range from 0 to 100.");
System.out.println(); // print a blank line
// initialize variables and create a Scanner object
int scoreTotal;
int scoreCount;
int testScore;
Scanner sc = new Scanner(System.in);
// perform calculations until choice isn't equal to "y" or "Y"
String choice = "y";
while (!choice.equalsIgnoreCase("n"))
{
// get the number of grades to be averaged from the user
System.out.print("How many scores would you like to average? ");
scoreCount = sc.nextInt();
// get the input from the user
System.out.print("Enter score: ");
testScore = sc.nextInt();
// accumulate score count and score total
if (testScore <= 100)
{
scoreTotal = scoreTotal + testScore;
}
else if (testScore >= 100)
System.out.println("Invalid entry, not counted");
// display the score count, score total, and average score
double averageScore = scoreTotal / scoreCount;
String message = "\n" +
"Score count: " + scoreCount + "\n"
+ "Score total: " + scoreTotal + "\n"
+ "Average score: " + averageScore + "\n";
System.out.println(message);
System.out.print("Would you like to average more grades? (y/n): ");
choice = sc.next();
System.out.println();
}
}
}
Your approach is near about right except some mistakes. You want to take input until 'n' is pressed and then the average would be shown. That means the average calculation must be done outside the loop, when taking input ends.
If you want to take input with a predefined number from input instead of 'y'/'n' approach, you can reuse your while loop:
int numOfInput = sc.nextInt(); // how many number will be entered
while(numOfInput > 0) {
// take every input and add to total
--numOfInput;
}
// average calculation
Also, a little logical mistake in input validation check.
if (testScore <= 100) // for less or equal 100
{
scoreTotal = scoreTotal + testScore;
}
else if (testScore >= 100) // for greater or equal 100
System.out.println("Invalid entry, not counted");
Both condition checks whether the number is equal to 100, which is not expected. If you allow only number less than 100, then you could write:
if (testScore < 100) {
scoreTotal += testScore;
}
else {
System.out.println("Invalid entry, not counted");
}
So you want to average scoreCount items, or keep averaging until the user has input "n" ?
If it's the first case (As you've described in your question) and you want to average for scoreCount times, you need to change the condition on your while loop.
System.out.print("How many scores would you like to average? ");
scoreCount = sc.nextInt();
scoreTotal = 0;
for(int i=0; i<scoreCount; i++){
scoreTotal += sc.nextInt();
System.out.print("Okay please enter next...");
}
System.out.print("Average is " + scoreTotal/scoreCount);
If you want to do it with a while, just keep an index, int index=0;, increment the index on each iteration and check if you've exceeded the index.
while (index < scoreCount)
scoreTotal += sc.nextInt();
index++;
System.out.print("Average is " + scoreTotal/scoreCount);
That is what you need:
for( int i = 0; i < scoreCount; i++){
System.out.print("Enter score: ");
testScore = sc.nextInt();
}
The for loop creates integer i to hold its looping index
int i;
And each loop asks is i bigger than scoreCount and if not loop again.
i < scoreCount;
And after each loop it adds one to i.
i++

Golf score program?

So I'm trying to make a program where it averages out your golf scores. I edited a standard averaging calculator to make it work:
import java.util.Scanner;
public class Test {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
int total = 0;
int score;
int average;
int counter = 0;
while (counter >= 0){
score = input.nextInt();
total = total + score;
counter++;
}
average= total/10;
System.out.println("Your average score is "+ average);
}
}
But when I enter scores, I can keep entering infinite scores and it never averages them. It just keeps expecting another score. I know it has something to do with this line:
while (counter >= 0){
but I'm not sure what to do so it works right.
You never find a way to break out of the loop:
while (counter >= 0){
score = input.nextInt();
total = total + score;
counter++;
}
will loop 2 billion times (no I'm not exaggerating) since you don't have another way to break out.
What you probably want is to change your loop condition to this:
int score = 0;
while (score >= 0){
This will break out when a negative score is entered.
Also, you have an integer division at the end. You want to make floating-point, so change the declaration to this:
double average;
and change this line to this:
average = (double)total / 10.;
You need some way to beak out of the loop. For example, entering -1:
int score = input.nextInt();
if (score < 0) { break; }
total += score;
You also seem to have a couple of errors in the calculation of the average:
Don't always divide by 10 - use the value of counter.
Use floating point arithmetic. If you need an int, you probably want to round to nearest rather than truncate.
For example:
float average = total / (float)counter;
You have to specify the counter value, the default value is 0, so the condition in the while is always true, so you will go in an infinite loop.
while (true) {
score = input.nextInt();
if (score == 0) {
break;
}
total = total + score;
counter++;
}
Now your program will realize you're done entering scores when you enter the impossible score 0.

Categories

Resources