How to exclude numbers from array sum/average/min/max? - java

I'm working on an assignment for class and I'm trying to figure out how to get the average of the numbers in my array while excluding the number -999 (used to indicate missing data) I've figured out how to get the sum/average/min/max and whatnot but I cannot figure out how to exclude that -999 from the search range. You can see in the first few methods a few of the things I've tried so far to figure this out. I can't even find anything on google that might even begin to explain what I'm supposed to be doing right now.
These are the instructions I'm following and the below is my current code, thanks for any input you may have.
/**
* WeatherComputation.java
*/
//Put any imports below this line.
import java.util.*;
/**
* Static methods library which compute averages and other
* computations on integer arrays of temperatures.
*
* #author Joel Swanson
* #version 03.29.2014
*/
public class WeatherComputation
{
/**
* Average an array of temperatures.
* #param temperatures An array storing temperatures as ints.
* #return Returns the average of the array of ints.
*/
public static double averageTemperature(int[] temperatures)
{
int sum = 0;
for (int i = 0; i < temperatures.length; i++)
{
sum += temperatures[i];
}
double average = sum / temperatures.length;
return average;
}
/**
* Find the highest in an array of temperatures.
* #param temperatures An array storing temperatures as ints.
* #return The largest value from the the array of ints.
*/
public static int highestTemperature(int[] temperatures)
{
int max = temperatures[0];
for (int i = 1; i < temperatures.length; i++)
{
if(temperatures[i] > max)
{
max = temperatures[i];
}
}
return max;
}
/**
* Find the lowest in an array of temperatures.
* #param temperatures An array storing temperatures as ints.
* #return The lowest value from the the array of ints.
*/
public static int lowestTemperature(int[] temperatures)
{
int min = 0;
Arrays.sort(temperatures);
while (true)
{
if (min == -999)
{
break;
}
if(min > -999)
{
min = temperatures[0];
}
}
for (int i = 1; i < temperatures.length; i++)
{
if (min < -999)
{
if (temperatures[i] < min)
{
min = temperatures[i];
}
}
}
return min;
}
/**
* Return the total number of missing days. That is days with
* -999 recorded as the temperatures.
* #param temperatures An array storing temperatures as ints.
* #return The number of -999s found.
*/
public static int numberMissing(int[] temperatures)
{
int count = 0;
return count;
}
/**
* Calculate heating degree day.
* #param max The highest temperature for a given day.
* #param min The lowest temperature for a given day.
* #return heating degree day data for this day.
*/
public static double hdd(int max, int min)
{
double hdd = 0.0;
return hdd;
}
/**
* Calculate cooling degree day.
* #param max The highest temperature for a given day.
* #param min The lowest temperature for a given day.
* #return cooling degree day data for this day.
*/
public static double cdd(int max, int min)
{
double cdd = 0.0;
return cdd;
}
/**
* Sum monthly heating degree days.
* #param max An array with the highest temperatures for each day
* in a given month.
* #param min An array with the lowest temperatures for each day
* in a given month.
* #return The sum of the heating degree days.
*/
public static double monthHdd(int[] max, int[] min)
{
double sum = 0.0;
return sum;
}
/**
* Sum monthly cooling degree days.
* #param max An array with the highest temperatures for each day
* in a given month.
* #param min An array with the lowest temperatures for each day
* in a given month.
* #return The sum of the cooling degree days.
*/
public static double monthCdd(int[] max, int[] min)
{
double sum = 0.0;
return sum;
}
}

You really want to use Java 8's stream operators for this. If I take your code, and leave out the methods that aren't implemented, and that don't describe what is actually being calculated, I get this:
/**
* WeatherComputation.java
*/
import java.util.*;
import java.util.stream.IntStream;
/**
* Static methods library which compute averages and other
* computations on integer arrays of temperatures.
*
* #author Joel Swanson
* #version 03.29.2014
*/
public class WeatherComputation {
/**
* Filters out all missing values (represented by -999).
*
* #param temperaturs an array storing temperatures as ints.
* #return the list with the missing values removed
*/
private static IntStream getFilteredArray(final int[] temperaturs) {
return IntStream.of(temperaturs)
.filter(i -> i != -999);
}
/**
* Average an array of temperatures.
*
* #param temperatures an array storing temperatures as ints.
* #return the average of the array of ints.
*/
public static double averageTemperature(int[] temperatures) {
// Returns 0 on an empty list. Your code will throw an exception
return getFilteredArray(temperatures).average().orElse(0d);
}
/**
* Find the highest in an array of temperatures.
*
* #param temperatures an array storing temperatures as ints.
* #return the largest value from the the array of ints.
*/
public static int highestTemperature(int[] temperatures) {
return getFilteredArray(temperatures).max().orElse(0);
}
/**
* Find the lowest in an array of temperatures.
*
* #param temperatures an array storing temperatures as ints.
* #return the lowest value from the the array of ints.
*/
public static int lowestTemperature(int[] temperatures) {
return getFilteredArray(temperatures).min().orElse(0);
}
/**
* Return the total number of missing days. That is days with
* -999 recorded as the temperatures.
*
* #param temperatures an array storing temperatures as ints.
* #return the number of -999s found.
*/
public static int numberMissing(int[] temperatures) {
return (int) IntStream.of(temperatures)
.filter(t -> t == -999)
.count();
}
}
The method getFilteredArray does all the work. It converts the array into an IntStream, it removes all -999 values, and returns the stream. Then you can use stream operators to calculate things like average, sum, minimum, maximum, etc.

public static double averageTemperature(int[] temperatures)
{
int sum = 0;
int count = 0;// number of valid values
for (int i = 0; i < temperatures.length; i++)
{
if(temperatures[i] > -999){ // before calculating check value
count ++;
sum += temperatures[i];
}
}
double average = count != 0 ? sum / count : -999 - 1; // preventing divide by zero
return average;
}
public static int lowestTemperature(int[] temperatures) {
if(temperatures == null || temperatures.length == 0)
return -999 - 1;
int min = temperatures[0];
for (int temperature : temperatures) {
if (temperature > -999 && temperature < min) {
min = temperature;
}
}
return min;
}

For the lowestTemperature, this is what I would do:
public static int lowestTemperature(int[] temperatures) {
int min = 999;
for (int temperature : temperatures) {
if (temperature > -999 && temperature < min) {
min = temperature;
}
}
return min;
}
Assuming that your WeatherComputation class would also consider 999 the same way as it would consider -999 (an invalid value). The reason is simple, what if you only have negative values during a month? Then, your int min = 0 would be incorrect.
As for the averageTemperature:
public static double averageTemperature(int[] temperatures) {
int sum = 0, validTemperatureCounter = 0;
for (int temperature : temperatures) {
if (temperature > -999 && temperature < 999) {
validTemperatureCounter++;
sum += temperature;
}
}
return sum / (double)validTemperatureCounter;
}
I also took the liberty of ignoring the value 999.
Update
For fun, one liners:
public static double averageTemperatureOneLiner(int[] temperatures) {
return Arrays.stream(temperatures).filter(t -> t > -999 && t < 999).average().orElse(0);
}
public static int lowestTemperatureOneLiner(int[] temperatures) {
return Arrays.stream(temperatures).filter(t -> t > -999 && t < 999).min().orElse(0);
}
public static int highestTemperatureOneLiner(int[] temperatures) {
return Arrays.stream(temperatures).filter(t -> t > -999 && t < 999).max().orElse(0);
}

You just need to check at each step if the value is the excluded one before using it in your sum/average/min/max methods.
For instance:
public static double averageTemperature(int[] temperatures)
{
int sum = 0;
int count = 0;
for (int i = 0; i < temperatures.length; i++)
{
if (temperatures[i] != -999) {
sum += temperatures[i];
count++;
}
}
double average = sum / count;
return average;
}

Related

Passing and updating an array of scores by increasing with given percentage

public class ScoreCard {
private double[] scores;
/**
*
* #param val
* #param low
* #param high
* #return low if val < low,
* high if val > high,
* val if val is between low and high
*/
private double constrain(double val, int low, int high) {
if (val < low)
return low;
if (val > high)
return high;
return val;
}
.
.
.
.
/**
* update each score so it increases by given percentage. For example,
* if score = {60.0, 90.0} before the method is called, it should
* become {72.0, 100.0} after the method is called with parameter 20.
* Note: 90.0 increased by 20% is 108, but scores should be constrained between
* 0 and 100. So, 100.
* #param percentage
*/
public void scale(double percentage) {
for (int i = 0; i < scores.length; i++) {
percentage = scores[i] / 100.0 * percentage;
scores[i] += constrain(percentage, 0, 100);
}
}
I've been stuck again on a little piece of code for a project. I am failing the JUnit tests when I try and pass this function. It seems to be correctly updating array with given percentage (10%) but instead of each item updating by the given percent, it seems to divide the percentage between the items inside the array, giving me ugly numbers.
Any assistance would be greatly appreicated!
Why are you changing the value of percentage in the loop?
I would do something like so:
for (int i = 0; i < scores.length; i++) {
scores[i] = constrain(scores[i]*(1+percentage/100), 0, 100);
}
public void scale(double percentage) {
for (int i = 0; i < scores.length; i++) {
percentage = scores[i] / 100.0 * percentage;
scores[i] =(scores[i]+percentage)>=100?100:(scores[i]+percentage);
}
}

Why does my arraylist stay empty despite adding objects?

I'm trying to make a method that factorizes the number n into the product of primes. For example factorizing 12 would result in 3 x 2^2. The first block of code factorizes n into loose numbers so 12 = 3 x 2 x 2 and places them in f. The second block is then supposed to store these numbers in p as powers instead of loose numbers by counting the exponent as the amount of times a number occurs in f, so 3^1 x 2^2 instead of 3 x 2 x 2. This is done with an object Power which stores the base and exponent of a number.
For some reason however, this code keeps returning empty arrays. And after looking it over many times I still have no idea why this would be the case. Is there something I'm doing wrong or that I misunderstand?
/**
* factorize n
*
* #param n the number to 'powerize'
* #modifies none
* #pre {#code 2 <= n}
* #return factorization of n
*/
public static List<Power> factorize(int n) {
List<Integer> f = new ArrayList<Integer>(); // f are factors
for (int i = 2; i <= n; i++) {
while (n % i == 0) {
f.add(i);
n /= i;
}
}
List<Power> p = new ArrayList<Power>(); // p are the factors with powers
for (int j = 2; j <= n; j++) { //j will be the base
int e = 0; //exponent
for (int k = 0; k <= f.size(); k++) {
if (f.get(k) == j) {
e++;
}
}
p.add(new Power(j, e));
}
return p; //returns factors in powered form
}
I'll add the code for the Power object in case it's necessary.
/**
* Record containing a base and an exponent.
*
* #inv {#code 0 <= base && 0 <= exponent}
*/
public static class Power { // BEGIN RECORD TYPE
/**
* The base.
*/
public int base;
/**
* The exponent.
*/
public int exponent;
/**
* Constructs a Power with given base and exponent.
*
* #param base the base
* #param exponent the exponent
* #pre {#code 0 <= base && 0 <= exponent}
* #post {#code \result.base == base && \result.exponent == exponent}
*/
public Power(int base, int exponent) {
this.base = base;
this.exponent = exponent;
}
} // END RECORD TYPE
if you debug you will see that your n variable value is 1 after first for cycle. That's why second cycle not started at all

Using int, double and long in calculation of powers

I'm having trouble figuring out when to use int, double and long.
I'm working on calculating the power of an integer and return the result as long as the power provided is not a negative number.
For the assignment, I'm required to use the following code to start:
public static long powerN(int number, int power) {
Here's what I came up with:
public class PowerCalculator
{
/**
* Calculate the non-negative power of an integer number. If a negative power is input, the method returns 1.
*
* #param number The number to take power.
* #param power The power factor to be taken to.
* #return The calculation result after taking power of the integer number.
*/
public static long powerN(int number, int power) {
if (power > 0)
{
double result = (Math.pow(number, power));
return result;
}
else
{
return 1;
}
}
}
I know I'm messing up the use of int, double or long but I don't know how to fix it.
Wait! If you're doing it yourself, use a faster algorithm like Exponentiation by squaring, something like this:
long powerN(long number, int power){
long res = 1;
long sq = number;
while(power > 0){
if(power % 2 == 1){
res *= sq;
}
sq = sq * sq;
power /= 2;
}
return res;
}
You could do it by yourself:
public static long powerN(
int number,
int power
) {
if(power == 0) return 1;
int result = number;
while(power > 1) {
result*=number;
power--;
}
return (long)result;
}
PS: This does not handle negative powers.
In case you'd like to use Math.pow:
public static long powerN(int number, int power) {
return (long) Math.pow(number, power);
}
Option 1: Cast result of Math.pow to long:
public class PowerCalculator{
/**
* Calculate the non-negative power of an integer number. If a negative power is input, the method returns 1.
*
* #param number The number to take power.
* #param power The power factor to be taken to.
* #return The calculation result after taking power of the integer number.
*/
public static long powerN(int number, int power) {
// write your code after this line
if (power < 0){
return 1;
} else{
return (long) Math.pow(number, power);
}
Option 2: without using Math.pow
public class PowerCalculator{
/**
* Calculate the non-negative power of an integer number. If a negative power is input, the method returns 1.
*
* #param number The number to take power.
* #param power The power factor to be taken to.
* #return The calculation result after taking power of the integer number.
*/
public static long powerN(int number, int power) {
// write your code after this line
long result = 1;
while (power > 0) {
result *= number;
power--;
}
return result;
}

Java - Print Contents of an Object

I am trying to print the contents of a of my object Fraction(), but it keeps giving me a lot of errors and referring me back to where my print statements start. I have a toString() method that I created, but that does not seem to work either. Here is my class and tester class:
package fraction;
public class Fraction
{
/**
* The numerator and denominator.
*/
private int top;
private int bottom;
/**
* Creates the fraction 0/1
*/
public Fraction()
{
top = 0;
bottom = 1;
}
/**
* Creates the fraction n/1
* #param n an integer
*/
public Fraction(int n)
{
top = n;
bottom = 1;
}
/**
* Creates a fraction with the specified numerator and denominator
* #param n the numerator
* #param d the denominator
*/
public Fraction(int n, int d)
{
top = n;
bottom = d;
if (bottom == 0) {
throw new IllegalArgumentException();
}
}
/**
* Computes the sum of this fraction and the specified fraction
* #param f a fraction
* #return the fraction obtained by adding this fraction from the specified fraction
*/
public Fraction add(Fraction f)
{
return new Fraction(this.numerator() * f.denominator() + f.numerator() * this.denominator());
}
/**
* Compares this fraction and the specified fraction
* #param f a fraction
* #return 0 when this fraction is equal to the specified fraction; 1 when this fraction is greater than the specified
* fraction; -1 otherwise
*/
public int compareTo(Fraction f)
{
if (top > f.numerator())
return 1;
else if (top < f.numerator())
return -1;
else if (bottom > f.denominator())
return 1;
else if (bottom < f.denominator())
return -1;
else
return 0;
}
/**
* Gives the denominator of this fraction
* #return the denominator of this fraction
*/
public int denominator()
{
return bottom;
}
/**
* Gives the quotient of this fraction and the specified fraction
* #param f a fraction
* #return the fraction obtained by dividing this fraction by the specified fraction
* #throws IllegalArgumentException when the numerator equals 0
*/
public Fraction divide(Fraction f)
{
if (f.numerator() == 0) {
throw new IllegalArgumentException();
}
else
{
return new Fraction(this.numerator() * f.numerator(), this.denominator() * f.denominator());
}
}
/**
* Determines whether this fraction is equal to the specified fraction
* #param f a fraction
* #return true when this fraction is equal to the specified fraction; otherwise, false
*/
public boolean equals(Fraction f)
{
return top == f.numerator() && bottom == f.denominator();
}
/**
* Computes the greatest common divisor of the specified numbers
* #param num1 an integer
* #param num2 an integer
* #return the greatest common divisor of the specified parameters
*/
private int gcd(int num1, int num2)
{
if (num2 == 0) {
return num1;
}
else
{
return gcd(num2, num1%num2);
}
}
/**
* Calculates the product of this fraction and the specified fraction
* #param f a fraction
* #return the product of this fraction and the specified fraction
*/
public Fraction multiply(Fraction f)
{
return new Fraction(this.numerator() * f.numerator(), this.denominator() * f.denominator());
}
/**
* Simplifies this fraction by expressing its numerator and denominator in standard form:
* the denominator is positive and the numerator and denominator are relative primes
*/
public void normalize()
{
int gcd = gcd(top,bottom);
top /= gcd;
bottom /= gcd;
}
/**
* Gives the numerator of this fraction
* #return the numerator of this fraction
*/
public int numerator()
{
return top;
}
/**
* Computes the reciprocal of this fraction
* #return the reciprocal of this fraction
* #throws IllegalArgumentException when the numerator is equal to 0
*/
public Fraction reciprocal()
{
if (top == 0) {
throw new IllegalArgumentException();
}
int temp;
temp = numerator();
top = denominator();
bottom = temp;
return new Fraction(top, bottom);
}
/**
* Modifies this fraction
* #param n the new numerator of this fraction
* #param d the new denominator of this fraction
* #throws IllegalArgumentException when the denominator equals 0
*/
public void setFraction(int n, int d)
{
if (d == 0) {
throw new IllegalArgumentException();
}
top = n;
bottom = d;
}
/**
* Computes the difference of this fraction and the specified fraction
* #param f a fraction
* #return the fraction obtained by subtracting this fraction from the specified fraction
*/
public Fraction subtract(Fraction f)
{
return new Fraction(this.numerator() * f.denominator() - f.numerator() * this.denominator(), this.denominator() * f.denominator());
}
/**
* Gives a string representing this fraction in in-line notation, numerator/denominator
* #return a string representing this fraction in in-line notation, numerator/denominator
*/
#Override public String toString()
{
return String.format("%d/%d",top,bottom);
}
}
package fraction;
import java.util.Scanner;
public class FractionTester
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter the numerator and denominator of f1 > ");
int n1 = in.nextInt(), d1 = in.nextInt();
System.out.print("Enter the numerator and denominator of f2 > ");
int n2 = in.nextInt(), d2 = in.nextInt();
System.out.print("Enter the numerator and denominator of f3 > ");
int n3 = in.nextInt(), d3 = in.nextInt();
System.out.print("Enter the numerator and denominator of f4 > ");
int n4 = in.nextInt(), d4 = in.nextInt();
System.out.println();
Fraction f1 = new Fraction(n1, d1);
Fraction f2 = new Fraction(n2, d2);
Fraction f3 = new Fraction(n3, d3);
Fraction f4 = new Fraction(n4, d4);
System.out.printf("f1 = %d", f1);
System.out.printf("f2 = %d", f2);
System.out.printf("f3 = %d", f3);
System.out.printf("f4 = %d", f4);
if (f1.compareTo(f2) == 0) {
System.out.println("f1 = f2");
}
else if (f1.compareTo(f2) < 0) {
System.out.println("f1 < f2");
}
else {
System.out.println("f1 > f2");
}
if (f3.compareTo(f4) == 0) {
System.out.println("f1 = f2");
}
else if (f3.compareTo(f4) < 0) {
System.out.println("f1 < f2");
}
else {
System.out.println("f1 > f2");
}
System.out.println();
}
}
I am trying to print the contents of the objects f1, f2, f3, and f4. It says my error is on the first print statement (System.out.printf("f1 = %d", f1);).
Your fraction is not a number (%d) but an Object of which the toString() method should be called. Change %d to %s and it will work, i.e.
System.out.printf("f1 = %s", f1);
That's not how toString() works, change:
System.out.printf("f1 = %d", f1)
to:
System.out.println("f1 = "+ f1)
When you print an object its toString() will be called, which will return a String, while you where trying to print %d (a digit).

Class won't calculate what it should, also: sorting arrays of objects?

I'm trying to write a program that will allow the user to create "loan" objects and measure the total amount that they have to pay after putting it through an interest equation. I'm having two problems with it that i've been messing with for a few hours but can't figure out for some reason. The biggest problem is that the class that is supposed to calculate the total payment of the loan after plugging in variables, but it ALWAYS returns zero and I can't figure out why. Is it a problem with syntax? I created a test loan class to test out the program that creates ten random loans with ten random time lengths and both the "totalPay" and the "monthlyPay" (which is dependent on totalPay) is always zero.
The second problem is that I was trying to sort the ten random loans based on the numberOfYears of the loan, but I can't get it to work! I tried a few methods for sorting and the one I included is the most recent and probably the one that's the dumbest hahaha but it's the one that I was playing with most recently. I've included all the code below, any ideas?
Loan class:
(it's a little long but the important thing is just the main loan class, totalPayment, and monthlyPayment )
public class Loan {
double annualInterestRate = 2.5;
int numberOfYears = 1;
double loanAmount = 1000;
double base;
double exponent;
double totalPay;
String summary;
double monthly;
String[] list = new String[10];
String s;
/**
* creates default loan with 2.5 annual interest rate 1 year and 1000$
*/
public Loan(){
}
/**
* totalPay = amount(1+rate/12)^(year*12)
*
* #param anualInterestRate
* #param numberOfYears
* #param loanAmount
*/
public Loan(double anualInterestRate, int numberOfYears, double loanAmount){
base = (double) ( loanAmount * (1+anualInterestRate/12));
exponent = (double) (numberOfYears * 12);
totalPay = (double) Math.pow(base, exponent);
}
/**
*
* #return total payment
*/
public double totalPayment(){
return this.totalPay;
}
/**
*
* #return Monthly Payment
*/
public double monthlyPayment(){
monthly = (totalPay/12);
return monthly;
}
}
TestLoan:
import java.util.Random;
public class TestLoan {
public static void main (String[] args){
Random r = new Random();
Loan[] list = new Loan[10];
for (int i = 0; i < 10; i++){
Loan x = new Loan();
list[i] = x;
System.out.println(list[i].toString());
}
System.out.println();
System.out.println();
for (int i = 0; i < 9; i++){
list[i].setNumberOfYears(r.nextInt(30));
if (list[i].getNumberOfYears() > list[i+1].getNumberOfYears())
list[i] = list[i+1];
System.out.println(list[i].toString());
}
}
}
Thank you for looking!
Edit got rid of the irrelevant code
You set the number of years, but you never calculate the base, exponent or totalPay. That only happens in a constructor you never call.
What you need to do is move functional code out of the constructor and into a calculation method. That constructor should be for constructing the object.
old constructor:
public Loan(double anualInterestRate, int numberOfYears, double loanAmount) {
base = (double) (loanAmount * (1 + anualInterestRate / 12));
exponent = (double) (numberOfYears * 12);
totalPay = (double) Math.pow(base, exponent);
}
better way:
public Loan(double annualInterestRate, int numberOfYears, double loanAmount) {
this.annualInterestRate = annualInterestRate;
this.numberOfYears = numberOfYears;
this.loanAmount = loanAmount;
}
public void calculatePay() {
base = (double) (loanAmount * (1 + annualInterestRate / 12));
exponent = (double) (numberOfYears * 12);
totalPay = (double) Math.pow(base, exponent);
}
Also, your method for sorting is flawed. You should decide what a good natural ordering for Loan is, then implement the Comparable interface.
Then you could use an existing sort library like this:
for (int i = 0; i < 9; i++) {
list[i].setNumberOfYears(r.nextInt(30));
list[i].calculatePay();
}
Arrays.sort(list);
for (Loan loan: list) {
System.out.println(loan);
}

Categories