what is wrong with my method for avg? [duplicate] - java

This question already has answers here:
How do I get this code to stop input when the sum exceeds 100 and still preform the sum and average?
(2 answers)
Closed 9 years ago.
Yes, I know there are a lot of methods here. It's part of the assignment. In this code everything works as intended except that when numbers are entered that equal sum<=100, the "average" output is wrong. For example: if I put in 8,10,19 and zero to exit the output is count 3 sum 37 average 9.25.... the average should be 12.3333. Now, if i enter in 8, 10, 99 the output is count 3 sum 117 and average 39 which is correct. Why is it working for sum>100 but not sum<=100??? I don't get it. What am I missing?
public static void main(String[] args) {
//Use Main Method for gathering input
float input = 1;
// Declare variable for sum
float theSum = 0;
// Declare variable for average
float average = 0;
// Declare variable for counting the number of user inputs
int counter = 0;
/* Initialize the while loop using an input of 0 as a sentinel value
* to exit the loop*/
while (input != 0) {
if (input!=0){
counter++;
}
input = Float.parseFloat(
JOptionPane.showInputDialog(
null, "Please enter a number. Enter 0 to quit: "));
// Invoke sum method and pass input and summation to sum method
theSum = (sum(input, theSum));
if (theSum > 100)
{
JOptionPane.showMessageDialog(null, "The sum of your numbers "
+ "are greater than 100!");
break;
}
}
// Invoke display method and pass summation, average, and counter variables to it
average = (avg(theSum, counter));
display(theSum, average, counter);
}
public static float sum(float num1, float sum) {
//Add the user's input number to the sum variable
sum += num1;
//Return value of sum variable as new summation variable
return sum;
}
public static float avg(float num1, float num2) {
//Declare and initialize variable for average
//Calculate average
float average = num1 / num2;
//Return value of average variable
return average;
}
public static void display(float sum, float average, int counter) {
/* I am subtracting 1 from variable counter so as not to include the sentinel value
* of 0 that the user had to enter to exit the input loop in the overall count*/
// Display the count, sum, and average to the user
if (sum > 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter) + ", Sum = " + sum + ", Average = " + average);
}
if (sum <= 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter - 1) + ", Sum = " + sum + ", Average = " + average);
}
}
}

The reason is that you're exiting the while loop in different ways depending on the total sum. If the sum is less than 100, even when you enter the number 0 to "exit", you're still going through the loop an extra time. To be honest, the entire loop needs to be completely restructured; a do...while loop would be much easier to read and debug.

The issue is because of the way you exit the while loop as mentioned by #chrylis. So in case where the sum is <= 100 the counter is 1 larger. But when you print it you get correct result because you update the counter value here:
if (sum <= 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter - 1) + ", Sum = " + sum + ", Average = " + average);
}
As you see in your example:
"if I put in 8,10,19 and zero to exit the output is count 3 sum 37 average 9.25"
it is because the counter value is 4 (so the avg will be 37/4 = 9.25), but while displaying the result you subtract counter by 1, therefore you get the count as 3.
The do-while loop will solve the issue as the condition would be checked at the last thus the loop will exit in same manner for both <=100 and '>100`.
The do-while loop would be like this:
do{
//here goes your code
}while (input != 0);

Your counter is 1 larger than necessary. Dividing by (counter - 1) would fix it.

Related

Problem with while loop and if/else statement

I'm just having a bit of a problem with the output of this program (mostly the if/else statement). The problem is the if statement output duplicates itself and gives 2 separate answers while the else statement prints out like it's supposed to but wrong integer and result.
I'm trying to get the output something like this.
Example:
The sum of the values above the threshold of 62 is blahblahblah
The sum of the values below the threshold of 62 is blahblahblah
However, my program is printing out something like this (I'm trying to get it to print out the 50 in the integer variable slot for both outputs):
Example #'s: 30, 60, 50, 20, 10, 40
The sum of the values above the threshold of 30 is 30
The sum of the values above the threshold of 50 is 80
The sum of the values below the threshold of 10 is 90
import java.util.*;
import java.io.*;
public class ThresholdTotals {
public static void main (String [] args) throws Exception {
Scanner sc = new Scanner (new File ("values.text"));
int num = 0;
int max = 0;
int sum = 0;
while (sc.hasNextInt()) {
num = sc.nextInt();
max = sc.nextInt(); // used to print the 2nd highest max
if (num >= max) {
sum += num;
System.out.println("The sum of the values above the threshold of " + num + " is " + sum);
// prints out a certain integer and the sum of the values greater than it
}
else {
sum += num;
System.out.println("The sum of the values below the threshold of " + num + " is " + sum);
// prints out a certain integer and the sum of the values less than it
}
}
sc.close();
}
}

My if statements will not take new values

The object is to get the average of the entered values.
It is to stop when a negative number is entered.
I am trying to get the smallest and largest values entered.
The problem I am having is that my if statements will not take the smallest/largest new values entered.
It just gives me the Integer.Max_Value and Integer.Min_Value.
import java.util.Scanner;
public class LargeSmallAverage {
public static void main(String[] args) {
// TODO Auto-generated method stub
double count = 0;
double amtOfNums = 0;
int input = 0;
int smallest = Integer.MAX_VALUE, largest = Integer.MIN_VALUE;
int number;
System.out.println("Enter a series of numbers. Enter a negative number to quit.");
Scanner scan = new Scanner(System.in);
while ((input = scan.nextInt()) > 0) {
count += input;
amtOfNums++;
}
while(input>=0){
for(int counter=1; counter<amtOfNums; counter++){
number=scan.nextInt();
if(number<smallest)
smallest=number;
if(number>largest)
largest=number;
}
}
System.out.println("You entered " + amtOfNums + " numbers averaging " + (count/amtOfNums) + ".");
System.out.println("The smallest number is "+ smallest);
System.out.println("The largest number is " + largest);
}
}
Currently you have two loops. One sums the numbers, and the other finds the largest and smallest numbers. Given your output, it sounds like you should be doing it all in one loop - ideally with more useful variable names too. (Your count is actually a sum, not a count... and there's no need for it to be a double. You could make it a long if you really want to avoid overflow. Yes, you need to perform floating point arithmetic for your average, but you can do that when you take the average... your sum is logically an integer.)
int sum = 0;
int smallest = Integer.MAX_VALUE;
int largest = Integer.MIN_VALUE;
int count = 0;
while ((input = scan.nextInt()) >= 0) {
count++;
sum += input;
// Alternative: smallest = Math.min(smallest, input)
if (input < smallest) {
smallest = input;
}
// Alternative: largest = Math.max(smallest, input)
if (input > largest) {
largest = input;
}
}
// Cast for count is just to force floating point division.
System.out.println("You entered " + count +
" numbers averaging " + (sum / (double) count) + ".");
System.out.println("The smallest number is "+ smallest);
System.out.println("The largest number is " + largest);
There is a problem with your while loop condition: while(input>=0){
here input will be always less than zero due to your previous while statement:while ((input = scan.nextInt()) > 0)
Here while loop exits only when you enter a number which is less than zero.. so input will have that value..

Average Calculator [ rounding issues ]

I have been assigned a task to create a average calculator, unfortunately each time a average is done I get either one too many which doesn't fix the issue when I do number -- OR, the average is completely off.
import java.util.*;
public class Mean
{
public static void main()
{
Scanner inputLine = new Scanner(System.in);
int total = 0, number, counter = 0;
double average;
System.out.println ("Enter your numbers, press 0 to launch");
while (inputLine.nextInt() != 0)
{
number = inputLine.nextInt();
if(number >= 1)
{
total = total + number;
counter++;
}
}
average = total/counter-1;
System.out.println ("Your Average is : " + average);
}
}
You are reading an int from the Scanner twice per loop. The while loop reads an int to make sure it's not 0, but then the body of the while loop reads a second int and only counts that second int.
Assign the result of the first nextInt call to a variable in the while loop condition, and use that variable in the body for the calculations.
You are subtracting 1 from your average calculation. There's no reason for that. Don't do it.
You are performing Java's integer division, which will truncate any decimals. Cast one of the operands to / to double to force floating-point calculations.
while ( (number = inputLine.nextInt() ) != 0)
{
if(number >= 1)
{
total = total + number;
counter++;
}
}
average = (double) total / counter;
You may want to add code for a condition where the user entered no items, to prevent dividing by 0.

Result no initialized?

import java.util.*;
//Creates a program which allows the user to find the factorial of a number
public class forLoop {
public static void main (String [] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the number you want the factorial from: ");
int number = input.nextInt(); // user input
input.close();
int result_2 = getFactorial(number); //initializes getFactorial method
System.out.println("The factorial of " + number + " is " + result); //prints results
}
public static int getFactorial (int num1) {
int result;
for (int times = num1; times <= 1; times--) { //repeats loop until times <=1
result = num1 * (num1 - 1); //does the factorial equation
}
return result; // returns results (here is the problem)
}
}
The compiler cannot assume that the loop would execute at least once - a necessary condition for the result to get assigned.
Change declaration of result as follows to fix the problem:
int result = 1;
This would help your code compile, but it would not fix the logical error in calculating the factorial: currently, your loop would run indefinitely because of a wrong loop condition.
You should be multiplying numbers from 1 to num1, inclusive. Change the loop condition so times >= 1 instead of times <= 1, and the loop body to result *= times to fix this error.
You need to intialize this variable:
int result;
Like this:
int result = 0; //Which ever intial value you want
Because compiler will not be sure that for loop will be always executed.
The condition of for loop is incorrect
it shoud be
for (int times = num1; times >= 1; times--)
{
result *= times; //this wil calculate right factorial
}
also initialize result to 1 before for loop
since you are assigning the function return value to result_2, you should print that instead of result
try
System.out.println("The factorial of " + number + " is " + result_2);
And you are need to initialize local variable before using them
int result;
for (int times = num1; times <= 1; times--) { //repeats loop until times <=1
result = num1 * (num1 - 1); //does the factorial equation
}
This block is causing the error. If the loop does not run even once due to this
times <=1
condition java wont have anything to print here
System.out.println("The factorial of " + number + " is " + result);
So here comes the need of initialization which acts as a default value to print.
So the solution will be to replace
int result;
with
int result=1; // note that I am not initializing with 0 as that will cause every factorial to become zero.
there is another mistake in your code instead of
times <= 1
it should be
times >= 1
Your code will probably not run even once for this error.
Just initialize int result to something:
int result = 0;
Because your loop isn't executing (times is already greater than 1), it is trying to return an uninitialized variable.

Can you help me fix the average portion of my code? [duplicate]

This question already has answers here:
How do I get this code to stop input when the sum exceeds 100 and still preform the sum and average?
(2 answers)
Closed 9 years ago.
When I run this code and input numbers whose sum>100 the output is correct for the count and the sum but the average is wrong. For example; input 8,10,99... the count is 3, the sum is 117 and should return an average of 39... the actual output returned is count 3, sum 117 and average 58.5. I have come to realize this is because the average is being done using a count of 2 instead of 3(or always one less than it should be with different values). Why is this? It works perfect for inputs sum<=100. PLEASE HELP :)
public static void main(String[] args) {
//Use Main Method for gathering input
float input = 1;
// Declare variable for sum
float theSum = 0;
// Declare variable for average
float average = 0;
// Declare variable for counting the number of user inputs
int counter = 0;
/* Initialize the while loop using an input of 0 as a sentinel value
* to exit the loop*/
while (input != 0) {
// Use JOptionPane method to accept input from user
input = Float.parseFloat(
JOptionPane.showInputDialog(
null, "Please enter a number. Enter 0 to quit: "));
// Invoke sum method and pass input and summation to sum method
theSum = (sum(input, theSum));
// Invoke avg method and pass summation and counter to avg
average = (avg(theSum, counter));
// Increment the counter variable
counter++;
if (theSum > 100)
{
JOptionPane.showMessageDialog(null, "The sum of your numbers "
+ "are greater than 100!");
break;
}
}
// Invoke display method and pass summation, average, and counter variables to it
display(theSum, average, counter);
}
public static float sum(float num1, float sum) {
//Add the user's input number to the sum variable
sum += num1;
//Return value of sum variable as new summation variable
return sum;
}
public static float avg(float num1, int num2) {
//Declare and initialize variable for average
float average = 0;
//Calculate average
average = num1 / num2;
//Return value of average variable
return average;
}
public static void display(float sum, float average, int counter) {
/* I am subtracting 1 from variable counter so as not to include the sentinel value
* of 0 that the user had to enter to exit the input loop in the overall count*/
// Display the count, sum, and average to the user
if (sum > 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter) + ", Sum = " + sum + ", Average = " + average);
}
if (sum <= 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter - 1) + ", Sum = " + sum + ", Average = " + average);
}
}
}
You increment the counter after taking average, which is why you see your average based on 2 numbers rather than your expected 3.
average = (avg(theSum, counter));
// Increment the counter variable
counter++;
Swap those two and increment counter before you take average.
counter++;
// Increment the counter variable
average = (avg(theSum, counter));
Edit:
Here is what you should change:
First, update the counter only if input is not = 0
if(input!=0)
{
counter++;
}
Secondly, move the average code out of the loop and it put it in the end just before display, don't need to compute average again and again.
average = (avg(theSum, counter));
display(theSum, average, counter);
Thirdly, remove counter-1 from display method and print counter
public static void display(float sum, float average, int counter) {
JOptionPane.showMessageDialog(null, "Count = " + (counter) + ", Sum = " + sum + ", Average = " + average);
}
After that, it works for both cases like you expect

Categories