Average rainfall

The problem

Write a program that uses nested loops to collect data and calculate the average rainfall over a period of years. The program should first ask for the number of years. The outer loop will iterate once for each year. The inner loop will iterate twelve times, once for each month. Each iteration of the inner loop will ask the user for the inches of rainfall for that month. After all iterations, the program should display the number of months, the total inches of rainfall, and the average rainfall per month for the entire period.

Breaking it down

Calculate sum and average

static double calculateTotalRainFall(List<Double> rainFall) {

    Double sum = new Double(0);
    for (Double i : rainFall) {
        sum = sum + i;
    }
    return sum;
}

static double calculateAverageRainFall(List<Double> rainFall) {

    Double sum = 0d;
    for (Double vals : rainFall) {
        sum += vals;
    }

    return sum = sum / rainFall.size();
}

Putting it together

final static int NUM_MONTHS = 12; // Months per year

public static void main(String[] args) {

    int years; // Number of years
    double monthRain;
    List<Double> rainFall = new ArrayList<Double>();

    // Create a Scanner object for keyboard input.
    Scanner keyboard = new Scanner(System.in);

    // Get the number of years.
    System.out.print("Enter the number of years: ");
    years = keyboard.nextInt();

    // Validate the input.
    while (years < 1) {
        System.out.print("Invalid. Enter 1 or greater: ");
        years = keyboard.nextInt();
    }

    System.out.println("Enter the rainfall, in inches, "
            + "for each month.");

    for (int y = 1; y <= years; y++) {

        for (int m = 1; m <= NUM_MONTHS; m++) {

            // Get the rainfall for a month.
            System.out.print("Year " + y + " month " + m + ": ");
            monthRain = keyboard.nextDouble();

            // Accumulate the rainfall.
            rainFall.add(new Double(monthRain));
        }
    }

    // Display the statistics.
    System.out.println("\nNumber of months: " + (years * NUM_MONTHS));
    System.out.println("Total rainfall: "
            + calculateTotalRainFall(rainFall) + " inches");
    System.out.println("Average monthly rainfall: "
            + calculateAverageRainFall(rainFall) + " inches");

}

Output

Enter the number of years: 1
Enter the rainfall, in inches, for each month.
Year 1 month 1: 10
Year 1 month 2: 10
Year 1 month 3: 10
Year 1 month 4: 10
Year 1 month 5: 10
Year 1 month 6: 10
Year 1 month 7: 10
Year 1 month 8: 10
Year 1 month 9: 10
Year 1 month 10: 10
Year 1 month 11: 10
Year 1 month 12: 10

Number of months: 12
Total rainfall: 120.0 inches
Average monthly rainfall: 10.0 inches

Unit tests

@Test
public void test_calculateTotalRainFall () {

    List<Double> listToSum = new ArrayList<Double>();
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));

    Double sum = AverageRainfall.calculateTotalRainFall(listToSum);

    assertEquals(50, sum, 0);
}

@Test
public void test_calculateAverageRainFall () {

    List<Double> listToSum = new ArrayList<Double>();
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));
    listToSum.add(new Double(10));

    Double sum = AverageRainfall.calculateAverageRainFall(listToSum);

    assertEquals(10, sum, 0);
}

Level Up

  • Enhance program to print output in a matrix of months
  • Handle user input that isn't a number
  • Enhance output to show a running average and overall average