I am working on a school assignment, so I need some guidance on this. I am trying to write a program that reads a set of floating point data values from input. When the user indicates the end of the input my program must return the count of the values, the average, and the standard deviation.
I am able to the build the while loop to get the input and perform all of the other math functions. However, what I cannot figure out is how to get the count of the values entered by the user.
Here is what I have so far (minus the loop)
/**
This class is used to calculate the average and standard deviation
of a data set.
*/
public class DataSet{
private double sum;
private double sumSquare;
private int n;
/**Constructs a DataSet ojbect to hold the
* total number of inputs, sum and square
*/
public DataSet(){
sum = 0;
sumSquare = 0;
n = 0;
}
/**Adds a value to this data set
* #param x the input value
*/
public void add(double x){
sum = sum + x;
sumSquare = sumSquare + x * x;
}
/**Calculate average fo dataset
* #return average, the average of the set
*/
public double getAverage(){
//This I know how to do
return avg;
}
/**Get the total inputs values
* #return n, the total number of inputs
*/
public int getCount(){
//I am lost here, I don't know how to get this.
}
}
I cant use Array because we are not that far on the classes yet.
Unless I misunderstand the question all you need to do is have a counter int. Every time add() is called you increase the counter using counter++;
EDIT: Your int n seems to be the intended counter. I'd change it to something more descriptive (like counter as suggested). Having a field which is a single letter is pretty bad practice.
Then all you have to do is return counter in your getCount method.
public void add(double x){
sum = sum + x;
sumSquare = sumSquare + x * x;
n++;
}
public int getCount(){
return n;
}
Related
I need to determine the minimum value after removing the first value.
For instance is these are the numbers 0.5 70 80 90 10
I need to remove 0.5, the determine the minimum value in the remaining numbers. calweightAvg is my focus ...
The final output should be “The weighted average of the numbers is 40, when using the data 0.5 70 80 90 10, where 0.5 is the weight, and the average is computed after dropping the lowest of the rest of the values.”
EDIT: Everything seems to be working, EXCEPT during the final out put. "The weighted average of the numbers is 40.0, when using the data 70.0, 80.0, 90.0, 10.0, where 70.0 (should be 0.5) is the weight, and the average is computed after dropping the lowest of the rest of the values."
So the math is right, the output is not.
EDIT: While using a class static double weight=0.5;to establish the weight, if the user were to change the values in the input file, that would not work. How can I change the class?
/*
*
*/
package calcweightedavg;
import java.util.Scanner;
import java.util.ArrayList;
import java.io.File;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
public class CalcWeightedAvg {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//System.out.println(System.getProperty("user.dir"));
ArrayList<Double> inputValues = getData(); // User entered integers.
double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.
printResults(inputValues, weightedAvg); //Weighted average of integers.
}
public class CalcWeightedAvg {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//System.out.println(System.getProperty("user.dir"));
ArrayList<Double> inputValues = getData(); // User entered integers.
double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.
printResults(inputValues, weightedAvg); //Weighted average of integers.
}
public static ArrayList<Double> getData() throws FileNotFoundException {
// Get input file name.
Scanner console = new Scanner(System.in);
System.out.print("Input File: ");
String inputFileName = console.next();
File inputFile = new File(inputFileName);
//
Scanner in = new Scanner(inputFile);
String inputString = in.nextLine();
//
String[] strArray = inputString.split("\\s+"); //LEFT OFF HERE
// Create arraylist with integers.
ArrayList<Double> doubleArrayList = new ArrayList<>();
for (String strElement : strArray) {
doubleArrayList.add(Double.parseDouble(strElement));
}
in.close();
return doubleArrayList;
}
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
Double weight = inputValues.get(0);
inputValues.remove(0);
//Sum and find min.
double min = Double.MAX_VALUE;
double sum = 0;
for (Double d : inputValues) {
if (d < min) min = d;
sum += d;
}
// Calculate weighted average.
return (sum-min)/(inputValues.size()-1) * weight;
}
public static void printResults(ArrayList<Double> inputValues, double weightedAvg) throws IOException {
Scanner console = new Scanner(System.in);
System.out.print("Output File: ");
String outputFileName = console.next();
PrintWriter out = new PrintWriter(outputFileName);
System.out.println("Your output is in the file " + outputFileName);
out.print("The weighted average of the numbers is " + weightedAvg + ", ");
out.print("when using the data ");
for (int i=0; i<inputValues.size(); i++) {
out.print(inputValues.get(i) + ", ");
}
out.print("\n where " + inputValues.get(0) + " is the weight, ");
out.print("and the average is computed after dropping the lowest of the rest of the values.\n");
out.close();
}
}
to do this task in a complexity of O(n) isn't a hard task.
you can use ArrayList's .get(0) to Save weight in a temp variable, then use .remove(0) function which removes the first value (in this case 0.5)
then you should use a For Each loop for (Double d : list) to sum AND find the minimal value
afterwards subtract the minimum value from the sum. and apply weight to the sum (in this case you'll end up with 240*0.5 = 120; 120\3 = 40;
finally, you can use ArrayList's .size()-1 function to determine the divisor.
The problem in your code:
in your implementation you've removed the weight item from list. then multiplied by the first item in the list even though it's no longer the weight:
return (sum-min)/(inputValues.size()-1) * inputValues.get(0);
your calculation than was: ((70+80+90+10)-10)/(4-1) * (70) = 5600
if(inputValues.size() <= 1){
inputValues.remove(0);
}
this size safeguard will not remove weight from the list. perhaps you've meant to use >=1
even if that was your intention this will not result in a correct computation of your algorithm in the edge cases where size==0\1\2 I would recommend that you re-think this.
the full steps that need to be taken in abstract code:
ArrayList<Double> list = new ArrayList();
// get and remove weight
Double weight = list.get(0);
list.remove(0);
// sum and find min
double min=Double.MAX_VALUE;
double sum=0;
for (Double d : list) {
if (d<min) min = d;
sum+=d;
}
// subtract min value from sum
sum-=min;
// apply weight
sum*=weight;
// calc weighted avg
double avg = sum/list.size()-1;
// viola!
do take notice that you can now safely add weight back into the array list after its use via ArrayList's .add(int index, T value) function. also, the code is very abstract and safeguards regarding size should be implemented.
Regarding your Edit:
it appears you're outputting the wrong variable.
out.print("\n where " + inputValues.get(0) + " is the weight, ");
the weight variable was already removed from the list at this stage, so the first item in the list is indeed 70. either add back the weight variable into the list after you've computed the result or save it in a class variable and input it directly.
following are the implementation of both solutions. you should only use one of them not both.
1) add weight back into list solution:
change this function to add weight back to list:
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
Double weight = inputValues.get(0);
inputValues.remove(0);
//Sum and find min.
double min = Double.MAX_VALUE;
double sum = 0;
for (Double d : inputValues) {
if (d < min) min = d;
sum += d;
}
// Calculate weighted average.
double returnVal = (sum-min)/(inputValues.size()-1) * weight;
// add weight back to list
inputValues.add(0,weight);
return returnVal;
}
2) class variable solution:
change for class:
public class CalcWeightedAvg {
static double weight=0;
//...
}
change for function:
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
weight = inputValues.get(0); // changed to class variable
//...
}
change for output:
out.print("\n where " + weight + " is the weight, ");
Since you're using an ArrayList, this should be a piece of cake.
To remove a value from an ArrayList, just find the index of the value and call
myList.remove(index);
If 0.5 is the first element in the list, remove it with
inputValues.remove(0);
If you want to find the minimum value in an ArrayList of doubles, just use this algorithm to find both the minimum value and its index:
double minVal = Double.MAX_VALUE;
int minIndex = -1;
for(int i = 0; i < myList.size(); i++) {
if(myList.get(i) < minVal) {
minVal = myList.get(i);
minIndex = i;
}
}
Hope this helps!
If you want to remove the first element from ArrayList and calculate the minimum in the remaining you should do:
if(inputValues.size() <= 1) //no point in calculation of one element
return;
inputValues.remove(0);
double min = inputValues.get(0);
for (int i = 1; i < inputValues.size(); i++) {
if (inputValues.get(i) < min)
min = inputValues.get(i);
}
I am a little unclear about your goal here. If you are required to make frequent calls to check the minimum value, a min heap would be a very good choice.
A min heap has the property that it offers constant time access to the minimum value. This [implementation] uses an ArrayList. So, you can add to the ArrayList using the add() method, and minValue() gives constant time access to the minimum value of the list since it ensures that the minimum value is always at index 0. The list is modified accordingly when the least value is removed, or a new value is added (called heapify).
I am not adding any code here since the link should make that part clear. If you would like some clarification, I would be more than glad to be of help.
Edit.
public class HelloWorld {
private static ArrayList<Double> values;
private static Double sum = 0.0D;
/**
* Identifies the minimum value stored in the heap
* #return the minimum value
*/
public static Double minValue() {
if (values.size() == 0) {
throw new NoSuchElementException();
}
return values.get(0);
}
/**
* Adds a new value to the heap.
* #param newValue the value to be added
*/
public static void add(Double newValue) {
values.add(newValue);
int pos = values.size()-1;
while (pos > 0) {
if (newValue.compareTo(values.get((pos-1)/2)) < 0) {
values.set(pos, values.get((pos-1)/2));
pos = (pos-1)/2;
}
else {
break;
}
}
values.set(pos, newValue);
// update global sum
sum += newValue;
}
/**
* Removes the minimum value from the heap.
*/
public static void remove() {
Double newValue = values.remove(values.size()-1);
int pos = 0;
if (values.size() > 0) {
while (2*pos+1 < values.size()) {
int minChild = 2*pos+1;
if (2*pos+2 < values.size() &&
values.get(2*pos+2).compareTo(values.get(2*pos+1)) < 0) {
minChild = 2*pos+2;
}
if (newValue.compareTo(values.get(minChild)) > 0) {
values.set(pos, values.get(minChild));
pos = minChild;
}
else {
break;
}
}
values.set(pos, newValue);
}
// update global sum
sum -= newValue;
}
/**
* NEEDS EDIT Computes the average of the list, leaving out the minimum value.
* #param newValue the value to be added
*/
public static double calcWeightedAvg() {
double minValue = minValue();
// the running total of the sum took this into account
// so, we have to remove this from the sum to get the effective sum
double effectiveSum = (sum - minValue);
return effectiveSum * minValue;
}
public static void main(String []args) {
values = new ArrayList<Double>();
// add values to the arraylist -> order is intentionally ruined
double[] arr = new double[]{10,70,90,80,0.5};
for(double val: arr)
add(val);
System.out.println("Present minimum in the list: " + minValue()); // 0.5
System.out.println("CalcWeightedAvg: " + calcWeightedAvg()); // 125.0
}
}
Write a class called Average that can be used to calculate average of several integers. It should contain the following methods:
A method that accepts two integer parameters and returns their average.
A method that accepts three integer parameters and returns their average.
A method that accepts two integer parameters that represent a range.
Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive).
Implement the class and write a program to test its methods and submit your source code (.java files).
I am stuck on part three, I don't even really understand the stipulation. Will I be using a floating point / double? Here is the program I have thus far:
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
int numb1, numb2, numb3, userInput;
System.out.println("Enter '2' if you wish to average two numbers enter '3' if you wish to average 3.");
Scanner keyboard = new Scanner(System.in);
userInput = keyboard.nextInt();
if (userInput == 2){
System.out.println("Enter two numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2));
System.exit(1);
}
if(userInput == 3){
System.out.println("Enter three numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
numb3 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2, numb3));
System.exit(1);
}
}
public static int average (int num1, int num2) {
return (num1 + num2) / 2;
}
public static int average (int numb1, int numb2, int numb3){
return (numb1 + numb2 + numb3) / 3;
}
}
Please don't re-ask the same question as you just asked here: http://stackoverflow.com/questions/19507108/java-averaging-program
Rather update your other post to reflect your new code / questions.
Now onto your question:
A method that accepts two integer parameters that represent a range. Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive). Implement the class and write a program to test its methods and submit your source code (.java files).
Lets start by declaring our method and we'll declare it as static to conform to your program (since you're not creating your own objects). Then we want to check if the parameters follow the assignment instructions and return values accordingly.
public static int getRange(int firstValue, int secondValue)
{
int range;
if (firstValue > secondValue)
range = firstValue - secondValue;
else
{
range = 0;
System.out.println("Error!");
}
return range;
}
**To promote your understanding it's up to you to find the average of the integers in the range!
Not really here to do your homework, but since I'm already here, the range is the difference between the largest and smallest number.
public int returnRange(int first, int second) {
if(first > second)
return first-second;
else
return second-first;
}
To make things easier though...
public double returnAverage(int...numbers) {
for(int i = 0; i < numbers.length(); i++) {
total += numbers;
}
return total/numbers.length();
}
public int returnRange(int...numbers) {
int holder = 0;
int highest;
int lowest;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] > holder) {
holder = numbers[i];
}
highest = holder;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] < holder) {
holder = numbers[i];
}
}
lowest = holder;
return highest-lowest;
}
Last 2 methods are un-tested, but from experience, should work fine. These methods have arrays for the parameters, so you can do as many numbers as you'd like.
In your main method check for -1 and return error when first value is greater than second
public double avgRange(int a, int b){
if(a>b){
return -1;
}
else{
double total=0;
for(int x=a; x<=b; x++){
total = total + x;
}
return total/(b-a+1);
}
}
the method should return the average of the integers in that range (inclusive).
You're asked to return the average of all integers in the range bounded by the two parameters.
For example, if parameters were 5 and 10, the method should return the average of 5, 6, 7, 8, 9, and 10, which is 7.5. (5 and 10 are included because the question says the range should be "inclusive".)
To find the average, use a for loop to sum each integer in the range, then divide by the number of integers.
Will I be using a floating point / double?
The return value should be a float or double, since the average isn't always a whole number.
The goal of this program is to take 2 random variables for a fraction and see if they are already in reduced terms or not. The supposed probability of this is 6/(pi^2). I run 1,000 different combinations of variables and determine how many were and were not already reduced. Then I solve for pi.
But the output is giving me "pi is 2.449489742783178" every time I run it.
Anyone know why? Thanks.
import java.util.*;
public class ratio1 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int nonReducedCount = 0; //counts how many non reduced ratios there are
for(int i =1; i<=1000; i++){
Random rand = new Random();
int n = rand.nextInt(1000)+1; //random int creation
int m = rand.nextInt(1000)+1;
//Ratio ratio = new Ratio(n,m);
if (gcd(n,m)> 1 ){ // if the ratio was not already fully reduced
nonReducedCount++; // increase the count of non reduced ratios
}
}
int reducedCount = 1000 - nonReducedCount; //number of times the ratio was reduced already
double reducedRatio = reducedCount / nonReducedCount; //the ratio for reduced and not reduced
reducedRatio *= 6;
reducedRatio = Math.sqrt(reducedRatio);
System.out.println("pi is " + reducedRatio);
}
public static int gcd(int a, int b) { return b==0 ? a : gcd(b,a%b); }
}
When you divide two integers, you get integer division, with an integer result, even if you later assign the result to a double. Try
double reducedRatio = (double)reducedCount / nonReducedCount;
i.e. convert one of the operands to a double.
I thought I had this figure out, and I was pretty confident it was going to work. Unfortunately, it did not.
The code below is supposed to return the average, the number of values entered and then calculate the std Var. I get it to return the average and count, but the std var result is off. Using the values 5, 6, 8 and 9 I am supposed to get a result of std var 1.83, I am getting something way off 7.17.
I know my error is in the way I am calculating the std Dev, but I was pretty sure I was doing it right.
Here is my code:
/**
This class is used to calculate the average and standard deviation
of a data set.
*/
public class DataSet{
private double sum;
private double sumSquare;
private int counter;
/**Constructs a DataSet object to hold the
* total number of inputs, sum and square
*/
public DataSet(){
sum = 0;
sumSquare = 0;
counter = 0;
}
/**Adds a value to this data set
* #param x the input value
*/
public void add(double x){
sum = sum + x;
sumSquare = sumSquare + x * x;
counter++;
}
/**Calculate average of dataset
* #return average, the average of the set
*/
public double getAverage(){
double avg = sum / counter;
return avg;
}
/**Get the total inputs values
* #return n, the total number of inputs
*/
public int getCount(){
return counter;
}
public double getStandardDeviation(){
double sqr = sumSquare / counter;
double stdDev = Math.sqrt(sqr);
return stdDev;
}
}
Here is my runner program:
import java.util.Scanner;
class DataSetRunner
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
DataSet data = new DataSet();
boolean done = false;
while (!done)
{
System.out.println("Enter value, Q to quit: ");
String userInput = input.next();
if (userInput.equalsIgnoreCase("Q"))
done = true;
else
{
double x = Double.parseDouble(userInput);
data.add(x);
}
}
System.out.println("Average = " + data.getAverage());
System.out.println("Count = " + data.getCount());
System.out.println("The Standard Deviation is = " + data.getStandardDeviation());
}
Your calculation is incorrect.
Standard deviation is based on the sum of the squares of the difference to the mean.
You are simply summing the squares of the data values.
You must first calculate the mean (ie the average), then once you know that you can calculate the standard deviation using this value.
The correct procedure is (quoting from wikipedia):
To calculate the population standard deviation, first compute the difference of each data point from the mean, and square the result of each:
Next, compute the average of these values, and take the square root:
Basically, you can't calculate the standard deviation "as you go".
I have created this program/scenario.
Multiple Robots are created and then "escape" from the room that has been created. I have also created a counter to count the moves that the robots make and then form an average.
I have created all this it only wants to return 0 for some reason. It's throwing up no errors or the like so I feel like I'm missing something obvious.
Here are both parts of the code:
public static double countingMoves;
.
.
.
public void move() {
super.move();
countingMoves++;
}
public int getRobotMoves() {
return countingMoves;
}
int Counter = EscapeBot.countingMoves/10;
int Counter = EscapeBot.countingMoves/10;
First Point
You're dividing two integers, which as stated in the comments, will result to 0 is the result is < 0. Cast one of these types to a double. This process is called Arithmetic Promotion, where every element in an expression has it's precision increased to the element with the highest precision. E.g:
int / int = int
double / double = double
int / double = double
int + String = String
For your code:
double Counter = EscapeBox.countingMoves/10.0;
Second Point
The Java naming convention states that the first word of variables or methods that are not constants must begin with a lower case letter.
Counter -> counter
Third and hopefully final point
If you look at where you are computing the average, 0.0 is actually correct. You compute the average at the start, before you have any moves.
double Counter = EscapeBot.countingMoves/10.0;
// When computed at the start, this equals:
// double Counter = EscapeBot.countingMoves(0)/10.0 = 0/10.0 = 0.0
Comes before any moves. By putting this at the end of your code, you should get a more accurate reading.