I wrote a program about calculating the average of raining in a year and give me the highest and the lowest amount but I am getting an error and I couldn't fix it.
This is my main code : `
public class Rainfall {
//field
private double [] rain;
public void Rainfall (double [] array) {
rain = new double [array.length] ;
for (int i=0; i < array.length ; i++)
rain [i] = array [i];
}
//Methods
public double getTotal() {
double total = 0;
for ( double r : rain)
total +=r;
return total;
}
public double getAverage () {
double a = getTotal () / rain.length;
return a;
}
public double getHighest () {
double highest = rain [0];
for (int i=0 ; i < rain.length; i++) {
if (rain [i] > highest) ;
highest = rain [i];
}
return highest;
}
public double getLowest () {
double lowest = rain [0];
for ( int i=0; i <rain.length; i++) {
if (rain [i] < lowest) ;
lowest = rain [i];
}
return lowest;
}
}
`
and this is the demo :
`
import java.util.Scanner;
import java.text.DecimalFormat;
public class RainFallDemo {
public static void main (String [] args ) throws NullPointerException
{
final int year1 = 12;
double [] rains = new double [year1];
getData (rains) ;
Rainfall rainfallData = new Rainfall ();
DecimalFormat values = new DecimalFormat ("#0.00") ;
System.out.println("The total rain is" + values.format(rainfallData.getTotal()));
System.out.println("The average is " + values.format (rainfallData.getAverage()));
System.out.println("The highest rain is " + values.format (rainfallData.getHighest()));
System.out.println("The lowest is " + values.format (rainfallData.getLowest()));
}
public static void getData (double [] array) {
Scanner keyboard = new Scanner (System.in) ;
for ( int i=0 ; i < array.length; i++)
{
System.out.println ("what was the amont of rain for month " + (i + 1) + "?");
array [i] = keyboard.nextDouble ();
while (array[i] < 0 )
{
System.out.print ( " Invalid input. You entered a negative number. Enter a" +
"value that is greater than zero");
array [i] = keyboard.nextDouble ();
}
}
}
}`
I was getting the wrong lowest and wrong highest and The program has to show which month had the lowest and highest in the output but but I can't figure out the code!!
Remove the semicolon at the end of your if lines. That is causing the if to execute an empty statement when it is true. Then the next line is always executed no matter what.
Related
For a homework assignment i need to take an unspecified number of grades( no more than 100), get the average, and display how many are above and below average. I'm trying to use a Sentinal value to exit the loop when putting in grades. And while it does exit the loop, it also takes the Sentinal value as a grade input and calculates that into the average. For example if I enter scores "50 75 100" then exit with -1. the results will display something like 74.66666666667. I can sort of see why it is doing this looking at my for loop but I'm struggling to find a way to fix it.
public class AnalyzeScores {
public static void main(String[] args) {
double scores, average;
int aboveAvg, belowAvg;
double sum = 0;
int count = 0;
Scanner input = new Scanner(System.in);
double[] scoresList = new double[100];
for (int i = 0; i < 100; i++) {
System.out.print("Enter Score " + (i + 1) + "(negative score exits): ");
scoresList[i] = input.nextDouble();
sum = sum + scoresList[i];
count++;
if (scoresList[i] < 0) {
average = (sum / i);
System.out.println("average is " + average);
return;
}
}
}
}
you should move this piece of code:
sum = sum + scoresList[i];
count++;
from before the if condition to after the if condition.
That's because you put -1 to your list while calculating the average. You need to check if the input value is below zero before adding it to scoresList.
Here is the code where this problem is fixed (but it still requires some improvements):
public class Main {
public static void main(String[] args) {
double scores, average;
int aboveAvg, belowAvg;
double sum = 0;
int count = 0;
Scanner input = new Scanner(System.in);
double[] scoresList = new double[100];
for (int i = 0; i < 100; i++) {
System.out.print("Enter Score " + (i + 1) + "(negative score exits): ");
double score = input.nextDouble();
if (score >= 0) {
scoresList[i] = score;
sum = sum + scoresList[i];
count++;
}
else break;
}
average = (sum / count);
System.out.println("average is " + average);
}
}
I have a method that calculates the minimum and maximum amount of rainfall from a user input array of months. My problem is that my method returns the quantity of min and max and I need it to return the month that had the highest or lowest amount of rainfall. I am not sure how to compare my min and max methods to the months array. I imagine if I could say the min was found at index 5 then have a way to pull index 5 of the month array as well.
I have tried multiple types of for loops and nested for loops but can not seem to get the correct month.
public static void main(String[] args) {
String[] months = {"January", "February", "March","April","May","June","July","August","September","October","November","December"};
double[] rainfall = new double[months.length];
Rainfall amazon = new Rainfall();
//scanner to get user input
Scanner scanner = new Scanner(System.in);
//for loop to iterate through the months to get user input of rainfall each month
for(int i = 0; i<rainfall.length; i++) {
System.out.println("How much rainfall did you recieve, in inches, for the month of: " + months[i]);
rainfall[i] = scanner.nextDouble();
//while statement to reject negative numbers
while(rainfall[i] < 0) {
System.out.println("You can not enter a negative number");
System.out.println("How much rainfall did you recieve for the month of: " + months[i]);
rainfall[i] = scanner.nextDouble();
}
}
System.out.println("total rainfall: " + amazon.getTotalRainfall(rainfall) +
" average Rainfall: " + amazon.getAverageRainfall(rainfall) +
" min: " + amazon.getMinRainfall(rainfall) +
" max: " + amazon.getMaxRainfall(rainfall));
}
public double getMaxRainfall(double[] rainfall) {
double max = rainfall[0];
for(int i = 1; i < rainfall.length; i++)
if(rainfall[i] > max) {
max = rainfall[i];
}
return max;
}
public double getMinRainfall(double[] rainfall) {
double min = rainfall[0];
for(int i = 1; i < rainfall.length; i++)
if(rainfall[i] < min) {
min = rainfall[i];
}
return min;
}
I need to know the month that had the highest and lowest amount of rainfall
The way you could solve this is by keeping track of the index of the highest rainfall instead of the value. The problem you have now is that you have 2 different arrays and the value from one does not relate back to the other.
For this you can do something like this:
public int getMaxRainfallIndex(double[] rainfall) {
int max = 0;
for (int i = 1; i < rainfall.length; i++)
if (rainfall[i] > rainfall[max]) {
max = i;
}
return max;
}
You can then use this return value to get the actual rainfall and month from the original 2 arrays.
A cleaner approach however, would be to make a separate class to store both pieces of information so you can return the whole object containing both pieces of information together. This way you wouldn't even have to worry about keeping 2 separate arrays.
That would be done like this:
public static void main(String[] args) {
Rainfall[] rainfall = new Rainfall[12];
//Do everything else
}
public class Rainfall {
private String month;
private double rainfall;
//Constructor, Getters + Setters
}
A possible solution will be to return the index of the month, so for example your getMaxRainfall method should look like this:
public int getMaxRainfallIndex(double[] rainfall)
{
int maxIndex = 0;
double max = rainfall[0];
for(int i = 1; i < rainfall.length; i++)
if(rainfall[i] > max)
{
max = rainfall[i];
maxIndex = i;
}
return maxIndex;
}
And in your main you should use that index to get both the month and the amount of rainfall:
int index = amazon.getMaxRainfallIndex(rainfall);
system.out.println("month of max rainfall: " + months[index]);
system.out.println("max rainfall: " + rainfall[index]);
Instead of managing two arrays separately, you could create a separate class:
public class RainfallByMonth {
private double rainfall;
private String month;
// Getter/Setters here
}
In your main method:
public static void main(String[] args) {
RainfallByMonth[] rainfallByMonths = new RainfallByMonth[12];
String[] months = new DateFormatSymbols().getMonths(); // array of months
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < rainfallByMonths.length; i++) {
System.out.println("How much rainfall did you receive, in inches, for the month of: " + months[i]);
rainfallByMonths[i].setMonth(months[i]);
rainfallByMonths[i].setRainfall(scanner.nextDouble());
}
RainfallByMonth maxRainfall = getMaxRainfall(rainfallByMonths);
// Now you can print the results here
}
Calculating max rainfall by month:
public static RainfallByMonth getMaxRainfall(RainfallByMonth[] rainfallByMonths) {
RainfallByMonth maxRainfall = rainfallByMonths[0];
for(int i = 1; i < rainfallByMonths.length; i++) {
if(rainfallByMonths[i].getRainfall() > maxRainfall.getRainfall()) {
maxRainfall = rainfallByMonths[i];
}
}
return maxRainfall;
}
Similarly, the vice versa for the min case (only the condition will be different). This will be much easier to manage.
public static void main(String[] args) {
String[] months = {"January", "February", "March","April","May","June","July","August","September","October","November","December"};
int[] weather = {10, -1, 7,44,33,6,22,54,89,21,8,51};
int max = 0;
int index= 0;
for (int i=0;i<weather.length-1;i++ ){
if (weather[i] > m){
max = weather[i];
index= i;
}
}
System.out.println(months[index]);
}
An example program to find highest month.
To find lowest month rainfall go with less than symbol in if condition
I need to break out of the for loop if the user enters 99999.The code below wont break the loop and actually calculates 99999 into the average. Thank you in advance for any help.
import java.util.*;
public class DistanceFromAverage {
public static void main(String[] args)
{
//User input
Scanner input = new Scanner(System.in);
double[] someNum = new double[10];
double sum = 0;
double avg;
for(int x =0; x < someNum.length; x++)
{
if(someNum[x] != 99999)
{
System.out.print("Enter a number >>");
someNum[x] = input.nextDouble();
sum = sum + someNum[x];
}
else
{break;}
}
//Figuring the average
avg = sum/10;
//Output
for(int y = 0; y < someNum.length; y++)
{
double distance = (someNum[y]-avg);
System.out.print(someNum[y]);
System.out.println(" Distance from average >> " + distance);
}
System.out.println("Average>> " + avg);
}
}
Your logic is messed up. You're asking for up to 10 numbers from the user. You've defaulted the array of input numbers to 0. When the user enters 99999, it gets added to the array, then on the next time through the loop, it looks for the next number to compare to 99999 and gets 0.
The entire logic should be rearranged to ask for up to 10 numbers, check the number immediately. If the user enters 99999, then break. Otherwise, put them into an array, keep a count, and average them.
I haven't tested this, but I've rearranged the logic a little which should set you on the right path.
List<Double> someNum = new ArrayList<Double>();
do {
System.out.print("Enter a number >>");
double thisNum = input.nextDouble();
if (thisNum == 99999) {
break;
}else {
someNum.add(thisNum);
sum += thisNum;
}
}while (true);
//Figuring the average
avg = someNum.size() == 0 ? 0 : sum / someNum.size();
for(double thisNum : someNum) {
double distance = (thisNum - avg);
System.out.print(thisNum);
System.out.println(" Distance from average >> " + distance);
}
//Output
System.out.println("Average>> " + avg);
How about using this as the for block:
System.out.print("Enter a number >>");
double inputValue = input.nextDouble();
if(inputValue == 99999){
break;
}
someNum[x] = inputValue;
sum = sum + someNum[x];
You won't be able to use x outside the loop as is, so use maybe another variable or maybe alter the for statement to not declare x to be local to the loop.
Using a well-thought-out while loop would be better.
You can use an ArrayList and simply specify the loop to increment 10 times for the getInput() method, and then specify the loop to only calculate average based on the .size() of the ArrayList.
This should fix it up for you, and break properly and calculate the average based on numbers input up until the 99999.
import java.util.*;
class DistanceFromAverage {
ArrayList<Double> numbers = new ArrayList<Double>();
double sum = 0;
double avg;
DistanceFromAverage() {
getInput();
calculateAverage();
showOutput();
}
void getInput() {
Scanner input = new Scanner(System.in);
for (int x = 0; x < 10; x++) {
System.out.println("Enter a number >>");
double num = input.nextDouble();
if (num == 99999) break;
else {
numbers.add(num);
sum += num;
}
}
}
void calculateAverage() {
avg = sum / 10;
}
void showOutput() {
for (int x = 0; x < numbers.size(); x++) {
double distance = (numbers.get(x) - avg);
System.out.println(numbers.get(x) + " Distance from average >> " + distance);
}
System.out.println("Average >> " + avg);
}
public static void main(String[] args) {
new DistanceFromAverage();
}
}
My original code is:
import javax.swing.JOptionPane;
public class average {
public static void main(String[] args) {
String str1;
String str2;
String str3;
int numbersToAverage;
str1 = JOptionPane.showInputDialog("Please enter the amount of numbers you would like to average: ");
numbersToAverage = Integer.parseInt(str1);
// while statement will provide error message so user cannot enter 0
while (numbersToAverage < 1) {
str3 = JOptionPane.showInputDialog("Invalid entry: Please enter one or more numbers to average: ");
numbersToAverage = Integer.parseInt(str3);
}
// array size is set to equal user input
double[] numbers = new double[numbersToAverage];
double sum = 0;
for (int i = 0; i < numbersToAverage; i++) {
str2 = JOptionPane.showInputDialog("Enter number " + (i + 1)
numbers[i] = Double.parseDouble(str2);
// the sum equals numbers in the array added together
sum += numbers[i];
}
// Calculates the average of the numbers entered by the user
double average = sum / numbersToAverage;
// Prints in a dialogue box to user the average
JOptionPane.showMessageDialog(null, "The average of the numbers you entered is: " + average);
}
}
and I am now having to calculate the average in a separate method and I am having a hard time figuring out how to do that? So far I have:
import javax.swing.JOptionPane;
public class average {
public static void main(String[] args) {
String str1;
String str2;
String str3;
int numbersToAverage;
str1 = JOptionPane
.showInputDialog("Please enter the amount of numbers you would like to average: ");
numbersToAverage = Integer.parseInt(str1);
// while statement will provide error message so user cannot enter 0
while (numbersToAverage < 1) {
str3 = JOptionPane
.showInputDialog("Invalid entry: Please enter one or more numbers to average: ");
numbersToAverage = Integer.parseInt(str3);
}
// array size is set to equal user input
double[] numbers = new double[numbersToAverage];
//double sum = 0;
for (int i = 0; i < numbersToAverage; i++) {
str2 = JOptionPane.showInputDialog("Enter number " + (i + 1)
numbers[i] = Double.parseDouble(str2);
JOptionPane.showMessageDialog(null, "The average of the numbers you entered is: " );
}
}
public static double average(double[] array){
double sum;
sum += array[i];
double average = sum / array.length;
return average;
}
}
I am having a hard time figuring out how to call this in the main method and how to get the correct calculation. What is the best way to do this? Do I need a for loop in the average method or should I keep it in the main?
Just do this:
StatUtils.mean(array);
you can find more about StatUtils here.
In Java 8 one might use Streams:
final double avg = array.length > 0 ? DoubleStream.of(array).sum() / array.length : 0;
Or in an own function:
public static double average(final double[] array) {
return array.length > 0 ? DoubleStream.of(array).sum() / array.length : 0;
}
Yes you need a loop, try to do something like this:
public static double average(double[] array) {
if(array.length == 0) {
return 0;
}
double sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
double average = sum / array.length;
return average;
}
This question already has answers here:
How to find the index of an element in an array in Java?
(15 answers)
Closed 6 years ago.
I am writing a java program that gets the rainfall for each month. It's working perfectly, but I just need to know how to get the index of a month - for example, there is an output statement: The month with the lowest amount of rain is 1 with 1.6 inches. How do I get the '1', which is the index of the lowest month? I can get the actual lowest rainfall figure fine, but not the index.
I have tried months[n-1], however I am still getting an error "non-static variable months cannot be referenced from a static context".
Any help would be great. Thanks.
// EDIT
Here is the code. I tried to play around with the static, but that just gave me more errors? So the months[n] part at the bottom is where I'm stuck.
import java.util.*;
public class Rainfall {
Scanner in=new Scanner(System.in);
int month=12;
double total=0;
double average;
double months[];
public Rainfall()
{
months=new double[12];
}
public void setMonths()
{
for(int n=1; n<=month; n++ )
{
System.out.print("Enter the rainfall (in inches) for month #"+n+": ");
months[n-1] = in.nextDouble();
//Input Validation - Cannot accept a negative number
while (months[n-1] < 0)
{
System.out.print("Rainfall must be at least 0. Please enter a new value.");
months[n-1] = in.nextDouble();
}
}
}
public double getTotalRainFall()
{
total = 0;
for(int i=0; i<12;i++)
{
total=total+months[i];
}
return total;
}
public double getAverageRainFall()
{
average = total/12;
return average;
}
public double getHighestMonth()
{
double highest=0;
for ( int i = 0; i < 12; i++)
{
if ( months[i] > highest)
{
highest = months[i] ;
}
}
return highest;
}
public double getLowestMonth()
{
double lowest = Double.MAX_VALUE;
for ( int n = 0; n < month; n++)
{
if (months[n] < lowest )
{
lowest = months[n];
}
}
return lowest;
}
public static void main(String[]args)
{
Rainfall r =new Rainfall();
r.setMonths();
System.out.println("The total rainfall for this year is " + r.getTotalRainFall());
System.out.println("The average rainfall for this year is " + r.getAverageRainFall());
System.out.println("The month with the highest amount of rain is " + months[n] + "with" + r.getHighestMonth() "inches");
System.out.println("The month with the lowest amount of rain is " + months[n] "with" + r.getLowestMonth() "inches");
}
}
/// EDIT #2 - Ok, so the above code works when getting user input for each month. Now I'm trying to set the values in the array thisYear (i.e. remove user input). The calculations no longer work. What have I done wrong?
package Rainfall;
public class Rainfall {
int month = 12;
double total = 0;
double average;
double getRainAt[];
public Rainfall() {
getRainAt = new double[12];
}
double getTotalRain() {
for (int i = 0; i < 12; i++) {
total = total + getRainAt[i];
}
return total;
}
double getAverageRain() {
average = total / 12;
return average;
}
int getHighestMonth() {
int high = 0;
for (int i = 0; i < 12; i++) {
if (getRainAt[i] > getRainAt[high]) {
high = i;
}
}
return high;
}
int getLowestMonth() {
int low = 0;
for (int i = 0; i < 12; i++) {
if (getRainAt[i] < getRainAt[low]) {
low = i;
}
}
return low;
}
public static void main(String[] args) {
// Create an array of rainfall figures.
double thisYear[] = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7,
3.9, 2.6, 2.9, 4.3, 2.4, 3.7 };
int high; // The high month
int low; // The low month
// Create a RainFall object initialized with the figures
// stored in the thisYear array.
Rainfall r = new Rainfall(thisYear);
// Display the statistics.
System.out.println("The total rainfall for this year is " +
r.getTotalRain());
System.out.println("The average rainfall for this year is " +
r.getAverageRain());
high = r.getHighestMonth();
System.out.println("The month with the highest amount of rain " +
"is " + (high+1) + " with " + r.getRainAt(high) +
" inches.");
low = r.getLowestMonth();
System.out.println("The month with the lowest amount of rain " +
"is " + (low+1) + " with " + r.getRainAt(low) +
" inches.");
}
}
non-static variable months cannot be referenced from a static context
This compile time time error comes when you access non static member from static member or block
like-
class Test{
private int i=0;
public static void main(String[] args){
i=1; //This will populate that error.
}
}
I think we can look this problem from little different way
class RainFall{
private double minFall;
private double maxFall;
public void setMinFall(double minFall) {
this.minFall = minFall;
}
public double getMinFall() {
return minFall;
}
public void setMaxFall(double maxFall) {
this.maxFall = maxFall;
}
public double getMaxFall() {
return maxFall;
}
}
public class RainFallMeasure{
public static void main(String[] args) {
Map<Integer,RainFall> rainFalls=new HashMap<Integer,RainFall>();
RainFall janRainFall = new RainFall();
janRainFall.setMinFall(1);
janRainFall.setMaxFall(1.6);
rainFalls.put(Calendar.JANUARY, janRainFall);
RainFall febRainFall = new RainFall();
...
rainFalls.put(Calendar.FEBRUARY, febRainFall);
}
}
You can find index with this method
public class TEST {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
double temp[] = {1, 5, 3};
System.out.print(getIndex(temp,3));
}
//takes 2 parameters one is array and other is the value for which you want find index
public static int getIndex(double[] temp, int value)
{
int i ;
for( i= 0; i< temp.length; i++)
{
if(temp[i] == value)
{
return i;
}
}
return -1;
}
}
In place of temp you can use your months while passing parameters.
An alternate approach is to redesign your application so that the methods compute the indexes of the months with the highest and lowest rainfall, instead of computing the rainfaill amounts themselves. The idea is that you can always lookup the actual values on demand, once you have the index.
I've patched the code for you so that it does just this, and took the liberty to correct a couple of "static" errors.
You can play with this working application and tune it as you wish:
import java.util.*;
public class Rainfall {
Scanner in = new Scanner(System.in);
int month = 12;
double total = 0;
double average;
double months[];
public Rainfall() {
months = new double[12];
}
public void enterMonthData() {
for (int n = 1; n <= month; n++) {
System.out.print("Enter the rainfall (in inches) for month #" + n + ": ");
months[n - 1] = in.nextDouble();
// Input Validation - Cannot accept a negative number
while (months[n - 1] < 0) {
System.out.print("Rainfall must be at least 0. Please enter a new value.");
months[n - 1] = in.nextDouble();
}
}
}
public double getTotalRainFall() {
total = 0;
for (int i = 0; i < 12; i++) {
total = total + months[i];
}
return total;
}
public double getAverageRainFall() {
average = total / 12;
return average;
}
/**
* Returns the index of the month with the highest rainfall.
*/
public int getHighestMonth() {
int highest = 0;
for (int i = 0; i < 12; i++) {
if (months[i] > months[highest]) {
highest = i;
}
}
return highest;
}
/**
* Returns the index of the month with the lowest rainfall.
*/
public int getLowestMonth() {
int lowest = 0;
for (int i = 0; i < 12; i++) {
if (months[i] < months[lowest]) {
lowest = i;
}
}
return lowest;
}
public static void main(String[]args) {
Rainfall r = new Rainfall();
r.enterMonthData();
System.out.println("The total rainfall for this year is " + r.getTotalRainFall());
System.out.println("The average rainfall for this year is " + r.getAverageRainFall());
int lowest = r.getLowestMonth();
int highest = r.getHighestMonth();
System.out.println("The month with the highest amount of rain is " + (highest+1) + " with " + r.months[highest] + " inches");
System.out.println("The month with the lowest amount of rain is " + (lowest+1) + " with " + r.months[lowest] + " inches");
}
}
ADDENDUM
To answer your follow-up question, you need to provide a constructor for your Rainfall object that takes in the rainfall data and store this data in a field of the object. This is what you want:
public class Rainfall {
private double[] amounts;
public Rainfall(double[] amounts) {
this.amounts = amounts;
}
double getTotalRain() {
double total = 0.0;
for (int i = 0; i < amounts.length; i++) {
total += amounts[i];
}
return total;
}
double getAverageRain() {
return getTotalRain() / amounts.length;
}
int getHighestMonth() {
int high = 0;
for (int i = 0; i < amounts.length; i++) {
if (amounts[i] > amounts[high]) {
high = i;
}
}
return high;
}
int getLowestMonth() {
int low = 0;
for (int i = 0; i < 12; i++) {
if (amounts[i] < amounts[low]) {
low = i;
}
}
return low;
}
/**
* Returns the total rain the given month number. Month numbers
* start at 0, not 1.
*/
double getRainForMonth(int monthNumber) {
return amounts[monthNumber];
}
public static void main(String[] args) {
// Sample data for testing
double thisYear[] = { 1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7 };
int high; // The high month, starting at 0
int low; // The low month, stating at 0
// Create a RainFall object initialized with amounts from above array.
Rainfall r = new Rainfall(thisYear);
// Display the statistics.
System.out.println("The total rainfall for this year is " + r.getTotalRain());
System.out.println("The average rainfall for this year is " + r.getAverageRain());
high = r.getHighestMonth();
System.out.println("The month with the highest amount of rain is " + (high + 1)
+ " with " + r.getRainForMonth(high) + " inches.");
low = r.getLowestMonth();
System.out.println("The month with the lowest amount of rain is " + (low + 1)
+ " with " + r.getRainForMonth(low) + " inches.");
}
}