3

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.");
    }
  }
SeekingCharlie
  • 607
  • 2
  • 8
  • 19
  • 1
    The "non-static" error is likely due to the fact that you declared your months array as a field of your application class and referenced it from your `main` method. Put `static` in front of your array to make that error go away. – Ray Toal May 04 '12 at 05:36
  • It would be great if you can provide the source code. It seems you are on correct path, but just as @Ray mentioned, you have to play with static. – Garbage May 04 '12 at 05:42
  • @RayToal - I've tried playing around with static, but still can't seem to get it to work. Can you see what I'm doing wrong from the code I posted? Thanks. – SeekingCharlie May 06 '12 at 03:42
  • Certainly. There was one issue with `months` having to be taken from `r`, so I went ahead and posted an answer with working code and also made some other suggestions as well. I realize its late so feel free to accept earlier answers if they are correct. – Ray Toal May 06 '12 at 04:07

3 Answers3

1

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);
    }
}
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
0

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.

Maddy
  • 3,726
  • 9
  • 41
  • 55
0

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.");
    }
}
Ray Toal
  • 86,166
  • 18
  • 182
  • 232