Trying to calculate user input with Double vs. double - java

Right now I'm working on a GUI that will calculate kinematic values based on what the user enters into a text field. I created a private inner class with values of type Double (not double), and then created a method to get a value based on values given. For example, this returns initial velocity:
public Double getInitialVelocity(Double vf, Double a, Double ti, Double tf) {
deltaT = deltaT(tf, ti);
initialVelocity = vf - (a * deltaT);
df.format(initialVelocity);
return initialVelocity;
}
The problem appears when I tried to test this method. I set up new doubles, and use getInitialVelocity in my main class:
Kinematics test = new Kinematics(); // creates object from inner class
Double vf = 1.0, a = 2.0, ti = 0.5, tf = 1.5;
test.getInitialVelocity(vf, a, ti, tf);
When I run this to test, I get this error:
Static Error: No method in Kinematics with name 'getInitialVelocity' matches this invocation
Arguments: (Double, Double, Double, Double)
Candidate signatures: double getInitialVelocity()
Does anyone know how to properly do this? I need to use type Double because I am comparing values given to null and then using the appropriate formula based on which values are null. Also, when converting from a String, should I just use Double.parseDouble(textField.getText()); ?
Edit 1: Here are the relevant parts of my class:
Private inner class (Kinematics):
private class Kinematics {
private Double initialVelocity, finalVelocity, acceleration, timeFinal, timeInitial;
private Double deltaT;
// constructor
public Kinematics() {
}
public Double deltaT(Double tf, Double ti) {
if(!(tf == null && ti == null)){
deltaT = tf - ti;
} return deltaT;
}
public Double getInitialVelocity(Double vf, Double a, Double ti, Double tf) {
deltaT = deltaT(tf, ti);
initialVelocity = vf - (a * deltaT);
df.format(initialVelocity);
return initialVelocity;
}
In my main class (KinematicsPanel), I have:
Kinematics values = new Kinematics();
viLabel = new JLabel("Initial Velocity: ");
viText = new JTextField(1);
vfLabel = new JLabel("Final Velocity: ");
vfText = new JTextField(1);
aLabel = new JLabel("Acceleration: ");
aText = new JTextField(1);
tiLabel = new JLabel("Initial Time: ");
tiText = new JTextField(1);
tfLabel = new JLabel("Final Time: ");
tfText = new JTextField(1);
// compute button & result
compute = new JButton("Compute");
compute.addActionListener(this);
result = new JTextField(2);
result.setEditable(false); // can not be edited
public void actionPerformed(ActionEvent e) {
String action = e.getActionCommand();
// parse each string to a value
Double vf = 0.0, a = 0.0, ti = 0.0, tf = 0.0;
if(vfText != null) {vf = Double.parseDouble(vfText.getText());}
if(aText != null) {a = Double.parseDouble(aText.getText());}
if(tiText != null) {ti = Double.parseDouble(tiText.getText());}
if(tfText != null) {tf = Double.parseDouble(tfText.getText());}
if(action.equals("Compute")) {
if(viText == null) { // get initial velocity
// get values
values.getInitialVelocity(vf, a, ti, tf);
System.out.println(values.toString()); // to test
result.setText(values.toString());
}
}
As of right now, this does nothing which is why I tested the method in the interactions pane in Dr.Java.
Edit2: The format function being used is in the main class:
DecimalFormat df = new DecimalFormat("#.00");

Its all ok with your code, which compiler are you using?
The method getInitialVelocity are in the class Kinematics?

it looks , you are using jdk 1.4 or lower one, there autoboxing is not supported.
so it can not convert Double to double. but that should give you a compile time
error if you are using IDE like eclipse.
OR
may be the method you are calling has different signature.
try to check the jdk version and post whole class if above one does no solve your problem.

Related

Cannot resolve symbol myLatitude

new to programming i know i'm doing something that's probably really obviously wrong to do with passing or using the wrong variables but i just can't work out what.
Here is my code:
public class CameraViewActivity extends Activity implements
SurfaceHolder.Callback, OnLocationChangedListener, OnAzimuthChangedListener {
private double mAzimuthReal = 0;
private double mAzimuthTheoretical = 0;
private static double AZIMUTH_ACCURACY = 5;
private double mMyLatitude = 0;
private double mMyLongitude = 0;
private List<Double> calculateAzimuthAccuracy(double azimuth) {
double minAngle = azimuth - AZIMUTH_ACCURACY;
double maxAngle = azimuth + AZIMUTH_ACCURACY;
List<Double> minMax = new ArrayList<Double>();
#Override
public void onAzimuthChanged(float azimuthChangedFrom, float azimuthChangedTo) {
mAzimuthReal = azimuthChangedTo;
mAzimuthTheoretical = calculateTheoreticalAzimuth();
pointerIcon = (ImageView) findViewById(R.id.icon);
double minAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(0);
double maxAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(1);
if (isBetween(minAngle, maxAngle, mAzimuthReaal) {
pointerIcon.setVisibility(View.VISIBLE);
}
else {
pointerIcon.setVisibility(View.INVISIBLE);
}
updateDescription();
}
Thanks for reading
Use
isRange(mMyLatitude, mMyLongitude, mPoi.getPoiLatitude(), mPoi.getPoiLongitude)
instead of
isRange(MyLatitude, MyLongitude, MpoiLatitude, MpoiLongitude)
FYI, its better to use small letter for naming variable.
In this function you need to pass as paramters either two locations and use their coordinates in the function inRange or you pass four coordinates and use them.
public void onAzimuthChanged(float azimuthChangedFrom, float azimuthChangedTo) {
mAzimuthReal = azimuthChangedTo;
mAzimuthTheoretical = calculateTheoreticalAzimuth();
pointerIcon = (ImageView) findViewById(R.id.icon);
double minAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(0);
double maxAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(1);
if (isBetween(minAngle, maxAngle, mAzimuthReal) && isRange(MyLatitude, MyLongitude, MpoiLatitude, MpoiLongitude)) {
pointerIcon.setVisibility(View.VISIBLE);
}
else {
pointerIcon.setVisibility(View.INVISIBLE);
}
updateDescription();
}
This has no meaning
isRange(MyLatitude, MyLongitude, MpoiLatitude, MpoiLongitude);
One more thing, adapt a professional naming criteria. Giving your attributes names that start with capital letters is quite MEH.

Generate Data Points for Graph from an equation

I don't want to solve an equation and my question is not about Graphs and Trees Data Structures. I am trying to generate Data Points for graph from an equation given by user. I want efficient algorithm, easy to use and easy to maintain data structures. I have two solutions in mind
1: This is trivial and I have seen in many Applications.
String expr = "2*x+3*x";
Evaluator evaluator = new Evaluator();//I have this class
for (int i = start; i < end; i += step)
{
evaluator.setConstant("x", i);
double ans = evaluator.evaluate(expr);
}
This is very slow because each time every step is repeated like tokenzing, verifying, conversion to RPN, preparing stacks and queues and at last result calculation. The possible solution to this problem is somehow caching all stacks and queues but after that a comparison would be required between current expression and previous expression to use last stored state.
2: Currently I am developing second solution. The purpose of this is efficiency and would be used in Symbolic calculation in future.
So far my implementation
Variable.java
import java.text.DecimalFormat;
public class Variable
{
private final double pow;
private final double coefficient;
private final String symbol;
public Variable(String symbol)
{
this.symbol = symbol;
this.pow = 1.0;
this.coefficient = 1.0;
}
public Variable(String symbol, double coefficient, double pow)throws IllegalArgumentException
{
if (coefficient == 0.0)throw new IllegalArgumentException("trying to create variable with coefficient 0");
if (pow == 0.0)throw new IllegalArgumentException("trying to create variable with exponent 0");
this.symbol = symbol;
this.pow = pow;
this.coefficient = coefficient;
}
public final String getSymbol()
{
return this.symbol;
}
public final double getPow()
{
return this.pow;
}
public final double getCoefficient()
{
return this.coefficient;
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
DecimalFormat decimalFormat = new DecimalFormat("#.############");
if (coefficient != 1.0)builder.append(decimalFormat.format(this.coefficient));
builder.append(this.symbol);
if (this.pow != 1.0)builder.append("^").append(decimalFormat.format(this.pow));
return builder.toString();
}
/*
* Stub Method
* Generate some unique hash code
* such that chances of key collision
* become less and easy to identify
* variables with same power and same
* symbol*/
#Override
public int hashCode()
{
return 0;
}
}
Equation.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class Equation
{
private final ArrayList<Boolean> operations;
private final HashMap<String, Variable> variableHashMap;
private int typesOfVariables;
public Equation(Variable variable)
{
this.variableHashMap = new HashMap<>();
this.operations = new ArrayList<>();
this.typesOfVariables = 1;
this.variableHashMap.put(variable.getSymbol(), variable);
}
/*Stub Method*/
public void addVariable(Variable variable, boolean multiply)
{
/*
* Currently not covering many cases
* 1: Add two variables which have same name
* and same pow.
* 2: variable which are wrapped inside functions e.g sin(x)
* and many other.*/
if (multiply && variableHashMap.containsKey(variable.getSymbol()))
{
Variable var = variableHashMap.get(variable.getSymbol());
Variable newVar = new Variable(var.getSymbol(), var.getCoefficient() * variable.getCoefficient(), var.getPow() + variable.getPow());
/*
* Collision chances for variables with same name but
* with different powers*/
this.variableHashMap.replace(var.getSymbol(), newVar);
}
else
{
++this.typesOfVariables;
this.variableHashMap.put(variable.getSymbol(), variable);
}
this.operations.add(multiply);
}
/*Stub Method
*Value for every variable at any point will be different*/
public double solveFor(double x)
{
if (typesOfVariables > 1)throw new IllegalArgumentException("provide values for all variables");
Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();
Variable var;
double ans = 0.0;
if (entryIterator.hasNext())
{
var = entryIterator.next().getValue();
ans = var.getCoefficient() * Math.pow(x, var.getPow());
}
for (int i = 0; entryIterator.hasNext(); i++)
{
var = entryIterator.next().getValue();
if (this.operations.get(i))ans *= var.getCoefficient() * Math.pow(x, var.getPow());
else ans += var.getCoefficient() * Math.pow(x, var.getPow());
}
return ans;
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();
if (entryIterator.hasNext())builder.append(entryIterator.next().getValue().toString());
Variable var;
for (int i = 0; entryIterator.hasNext(); i++)
{
var = entryIterator.next().getValue();
if (this.operations.get(i))builder.append("*").append(var.toString());
else builder.append(var.toString());
}
return builder.toString();
}
}
Main.java
class Main
{
public static void main(String[] args)
{
try
{
long t1 = System.nanoTime();
Variable variable = new Variable("x");
Variable variable1 = new Variable("x", -2.0, 1.0);
Variable variable2 = new Variable("x", 3.0, 4.0);
Equation equation = new Equation(variable);
equation.addVariable(variable1, true);//2x+x
equation.addVariable(variable2, true);
for (int i = 0; i < 1000000; i++)equation.solveFor(i);//Calculate Million Data Points
long t2 = System.nanoTime();
System.out.println((t2-t1)/1000/1000);
System.out.println(equation.toString());
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
}
}
}
Am I going in right direction?
Is there any commonly used Algorithm for this problem?
My main goal is efficiency, code cleanness and code maintainability.
Note: I am not native English speaker so please ignore any grammatical mistake.
Thanks.
I do not see any problem with your first code. Yes may be at every step your code "repeat like tokenzing, verifying, conversion to RPN, preparing stacks and queues and at last result calculation", but in the end all of this is just linear number of steps. So I fail to see how it can make it really slow.
One of the biggest screens I have seen was 2560x1440 pixels, which means that most of the time you would need less than 2500 points to draw your graph there.
If you point is code cleanness and code maintainability, then most probably a code consisting of 5 lines is better than the code consisting of 200.

Does my code calculate the Entropy/Conditional Entropy of a data set correctly?

I'm writing a java that I want to use to be able to calculate things like Entropy, Joint Entropy, Conditional Entropy, etc. when given a data set. The class in question is below:
public class Entropy {
private Frequency<String> iFrequency = new Frequency<String>();
private Frequency<String> rFrequency = new Frequency<String>();
Entropy(){
super();
}
public void setInterestedFrequency(List<String> interestedFrequency){
for(String s: interestedFrequency){
this.iFrequency.addValue(s);
}
}
public void setReducingFrequency(List<String> reducingFrequency){
for(String s:reducingFrequency){
this.rFrequency.addValue(s);
}
}
private double log(double num, int base){
return Math.log(num)/Math.log(base);
}
public double entropy(List<String> data){
double entropy = 0.0;
double prob = 0.0;
Frequency<String> frequency = new Frequency<String>();
for(String s:data){
frequency.addValue(s);
}
String[] keys = frequency.getKeys();
for(int i=0;i<keys.length;i++){
prob = frequency.getPct(keys[i]);
entropy = entropy - prob * log(prob,2);
}
return entropy;
}
/*
* return conditional probability of P(interestedClass|reducingClass)
* */
public double conditionalProbability(List<String> interestedSet,
List<String> reducingSet,
String interestedClass,
String reducingClass){
List<Integer> conditionalData = new LinkedList<Integer>();
if(iFrequency.getKeys().length==0){
this.setInterestedFrequency(interestedSet);
}
if(rFrequency.getKeys().length==0){
this.setReducingFrequency(reducingSet);
}
for(int i = 0;i<reducingSet.size();i++){
if(reducingSet.get(i).equalsIgnoreCase(reducingClass)){
if(interestedSet.get(i).equalsIgnoreCase(interestedClass)){
conditionalData.add(i);
}
}
}
int numerator = conditionalData.size();
int denominator = this.rFrequency.getNum(reducingClass);
return (double)numerator/denominator;
}
public double jointEntropy(List<String> set1, List<String> set2){
String[] set1Keys;
String[] set2Keys;
Double prob1;
Double prob2;
Double entropy = 0.0;
if(this.iFrequency.getKeys().length==0){
this.setInterestedFrequency(set1);
}
if(this.rFrequency.getKeys().length==0){
this.setReducingFrequency(set2);
}
set1Keys = this.iFrequency.getKeys();
set2Keys = this.rFrequency.getKeys();
for(int i=0;i<set1Keys.length;i++){
for(int j=0;j<set2Keys.length;j++){
prob1 = iFrequency.getPct(set1Keys[i]);
prob2 = rFrequency.getPct(set2Keys[j]);
entropy = entropy - (prob1*prob2)*log((prob1*prob2),2);
}
}
return entropy;
}
public double conditionalEntropy(List<String> interestedSet, List<String> reducingSet){
double jointEntropy = jointEntropy(interestedSet,reducingSet);
double reducingEntropyX = entropy(reducingSet);
double conEntYgivenX = jointEntropy - reducingEntropyX;
return conEntYgivenX;
}
For the past few days I've been trying to figure out why my Entropy calculation is almost always exactly the same as my calculation for conditional entropy.
I'm using the following formulas:
H(X) = - Sigma from x=1 to x=n p(x)*log(p(x))
H(XY) = - Sigma from x=1 to x=n,y=1 to y=m (p(x)*p(y)) * log(p(x)*p(y))
H(X|Y) = H(XY) - H(X)
The values that I get for my Entropy and Conditional Entropy are almost the same.
With the data set that I'm using for testing I get the following values:
#Test
public void testEntropy(){
FileHelper fileHelper = new FileHelper();
List<String> lines = fileHelper.readFileToMemory("");
Data freshData = fileHelper.parseCSVData(lines);
LinkedList<String> headersToChange = new LinkedList<String>();
headersToChange.add("lwt");
Data discreteData = freshData.discretize(freshData.getData(),headersToChange,1,10);
Entropy entropy = new Entropy();
Double result = entropy.entropy(discreteData.getData().get("lwt"));
assertEquals(2.48,result,.006);
}
#Test
public void testConditionalProbability(){
FileHelper fileHelper = new FileHelper();
List<String> lines = fileHelper.readFileToMemory("");
Data freshData = fileHelper.parseCSVData(lines);
LinkedList<String> headersToChange = new LinkedList<String>();
headersToChange.add("age");
headersToChange.add("lwt");
Data discreteData = freshData.discretize(freshData.getData(), headersToChange, 1, 10);
Entropy entropy = new Entropy();
double conditionalProb = entropy.conditionalProbability(discreteData.getData().get("lwt"),discreteData.getData().get("age"),"4","6");
assertEquals(.1,conditionalProb,.005);
}
#Test
public void testJointEntropy(){
FileHelper fileHelper = new FileHelper();
List<String> lines = fileHelper.readFileToMemory("");
Data freshData = fileHelper.parseCSVData(lines);
LinkedList<String> headersToChange = new LinkedList<String>();
headersToChange.add("age");
headersToChange.add("lwt");
Data discreteData = freshData.discretize(freshData.getData(), headersToChange, 1, 10);
Entropy entropy = new Entropy();
double jointEntropy = entropy.jointEntropy(discreteData.getData().get("lwt"),discreteData.getData().get("age"));
assertEquals(5.05,jointEntropy,.006);
}
#Test
public void testSpecifiedConditionalEntropy(){
FileHelper fileHelper = new FileHelper();
List<String> lines = fileHelper.readFileToMemory("");
Data freshData = fileHelper.parseCSVData(lines);
LinkedList<String> headersToChange = new LinkedList<String>();
headersToChange.add("age");
headersToChange.add("lwt");
Data discreteData = freshData.discretize(freshData.getData(), headersToChange, 1, 10);
Entropy entropy = new Entropy();
double specCondiEntropy = entropy.specifiedConditionalEntropy(discreteData.getData().get("lwt"),discreteData.getData().get("age"),"4","6");
assertEquals(.332,specCondiEntropy,.005);
}
#Test
public void testConditionalEntropy(){
FileHelper fileHelper = new FileHelper();
List<String> lines = fileHelper.readFileToMemory("");
Data freshData = fileHelper.parseCSVData(lines);
LinkedList<String> headersToChange = new LinkedList<String>();
headersToChange.add("age");
headersToChange.add("lwt");
Data discreteData = freshData.discretize(freshData.getData(), headersToChange, 1, 10);
Entropy entropy = new Entropy();
Double result = entropy.conditionalEntropy(discreteData.getData().get("lwt"),discreteData.getData().get("age"));
assertEquals(2.47,result,.006);
}
Everything compiles correctly but I'm pretty sure that my calculations for the conditional entropy are incorrect, but I'm not sure where I'm making a mistake.
The values that are in the unit tests are the values that I'm currently getting. They are the same as the output from the above functions.
At one point I was also using the following to do testing:
List<String> survived = Arrays.asList("1","0","1","1","0","1","0","0","0","1","0","1","0","0","1");
List<String> sex = Arrays.asList("0","1","0","1","1","0","0","1","1","0","1","0","0","1","1");
Where male = 1 and survived = 1. I then used this to calculate
double result = entropy.entropy(survived);
assertEquals(.996,result,.006);
as well as
double jointEntropy = entropy.jointEntropy(survived,sex);
assertEquals(1.99,jointEntropy,.006);
I also checked my work by calculating the values by hand. You can see an image here. Since my code was giving me the same values that I got when I did the problem by hand and since the other functions were pretty simple and just used the entropy/joint entropy functions I assumed that everything was fine.
However, something is going wrong. Below are two more functions that I wrote to calculate information gain and the symmetrical uncertainty of a set.
public double informationGain(List<String> interestedSet, List<String> reducingSet){
double entropy = entropy(interestedSet);
double conditionalEntropy = conditionalEntropy(interestedSet,reducingSet);
double infoGain = entropy - conditionalEntropy;
return infoGain;
}
public double symmetricalUncertainty(List<String> interestedSet, List<String> reducingSet){
double infoGain = informationGain(interestedSet,reducingSet);
double intSet = entropy(interestedSet);
double redSet = entropy(reducingSet);
double symUnc = 2 * ( infoGain/ (intSet+redSet) );
return symUnc;
}
The original survive/sex set that I used gave me an answer that was slightly negative. But since it was only negative by .000000000000002 I just assumed that it was a rounding error. When I tried to run my program, none of the values that I got for symmetrical uncertainty made any sense.
tldr; Your calculation for H(X,Y) apparently assumes that X and Y are independent, which results in H(X,Y) = H(X) + H(Y), which in turn results in your H(X|Y) being equal to H(X).
Is this your problem? If so, then use the correct formula for the joint entropy of X and Y (taken from Wikipedia):
You get your wrong one by substituting P(X,Y) = P(X)P(Y), which assumes that both variables are independent.
If both variables are independent, then indeed H(X|Y) = H(X) holds, because Y doesn't tell you anything about X, and consequently knowing Y doesn't decrease the entropy of X.
For calculating Entropy of single vector you can use below function
Function<List<Double>, Double> entropy =
x-> {
double sum= x.stream().mapToDouble(Double::doubleValue).sum();
return - x.stream()
.map(y->y/sum)
.map(y->y*Math.log(y))
.mapToDouble(Double::doubleValue)
.sum();
};
As an example using vector [1 2 3] would get you a result of 1.0114
double H = new Entropy().entropy.apply(Arrays.asList(new Double[] { 1.0, 2.0, 3.0 }));
System.out.println("Entropy H = "+ H);

Celsius to Fahrenheit in Java

I can convert from fahrenheit to celcius, but not the other way around. I have attached the code below. Hopefully it's enough to see what is going on.
public void actionPerformed(ActionEvent arg0) {
double temps = 0, temp1 = 0;
String instrings;
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temps = Double.parseDouble(instrings);
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temp1 = Double.parseDouble(instrings);
if(arg0.getActionCommand().equals("C")){
temps = (( temps * 9)/5+32);
DecimalFormat formatters = new DecimalFormat("#,###,###.###");
results.setText(""+formatters.format(temps));
}
else if(arg0.getActionCommand().equals("F"));
{
temp1 = (((temps - 32)/9)*5);
DecimalFormat formatters = new DecimalFormat("#,###,###.###");
results.setText(""+formatters.format(temp1));
}
}
Put a
System.out.println(arg0.getActionCommand());
in your method, and supposedly you will see that it is not "C" when using the Celsius button.
Generally, look at the console to see if there are any error messages around.
Another idea: You are using two double variables temps and temp1, parsing the instrings into both of them, and setting then one of them to the result. Why so complicated?
In general, I would recommend to not use the getActionCommand() method, but to give each button an own ActionListener. You can use an anonymous class for this. As both cases do almost the same, use two subclasses of a inner (or even local) class here:
abstract class ConversionListener implement ActionListener {
DecimalFormat formatter = new DecimalFormat("#,###,###.##");
public void actionPerformed(ActionEvent e) {
String input = temp.getText();
if (input.equals("")) {
input = "0";
temp.setText(input);
}
double number = Double.parseDouble(input);
results.setText(formatter.format(convert(number)));
}
/** to implement by subclasses */
abstract double convert(double number);
}
celsiusToFahrenheit.addActionListener(new ConversionListener() {
double convert(double celsius) {
return number * 9 / 5 + 32;
}
});
fahrenheitToCelsius.addActionListener(new ConversionListener() {
double convert(double fahrenheit) {
return (fahrenheit - 32) / 9 * 5;
}
});
Not sure what you are having trouble with but here is how to convert Celsius to Fahrenheit in Java.
float celsius = celsius value
float c=Float.parseFloat(celsius);
float f = 32 + 9*c/5;
Change from
temp1 = (((temps - 32)/9)*5);
to
temp1 = (((temps - 32)*5)/9);
instead.
On this part:
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temps = Double.parseDouble(instrings);
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temp1 = Double.parseDouble(instrings);
Am I missing something or is temps and temp1 both getting set to the same value? Or is it possible that between the temps assignment the temp.getText() could return a different value?
If it's the same, start by rewriting it to
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temps = Double.parseDouble(instrings);
temp1 = Double.parseDouble(instrings);
or even temp1 = temps
Also, some better naming of variables might be easier, temps, temp and temp1 are all very similar. One appears to be text from a control and the other 2 are numeric values.
Even names like 'inputTemperature' and 'calculatedTemperature' go a long way to making the code more readable.
This doesn't help solve your problem, but might help debugging in the future.

Barometric Formula in Java - Help

I'm learning Java and I wanted to create a very basic Calculator to calculate the air pressure at a certain height above sea level. However every time I try to build the code, I get an error about the local variable ... may not have been initialized.
import javax.swing.JOptionPane;
import java.lang.Math;
class barometer {
public static void main(String args[]){
String fn = JOptionPane.showInputDialog("Enter Height Above Sea Level in Metres:");
double h = Integer.parseInt(fn);
double R = 8.31432;
double g0 = 9.80665;
double M = 0.0289644;
double Pb, Tb, Lb, Hb;
String ans = "";
if (h<0){
ans = "error";
} else if (h>=0 && h<11000){
Pb = 101325.0;
Tb = 288.15;
Lb = -0.0065;
Hb = 0.0;
} else if (h>=11000 && h<20000){
Pb = 22632.1;
Tb = 216.65;
Lb = 0.0;
Hb = 11000.0;
} else if (h>=20000 && h<32000){
Pb = 5474.89;
Tb = 216.65;
Lb = 0.001;
Hb = 20000.0;
} else if (h>=32000 && h<47000){
Pb = 868.019;
Tb = 228.65;
Lb = 0.0028;
Hb = 32000.0;
} else if (h>=47000 && h<51000){
Pb = 110.906;
Tb = 270.65;
Lb = 0.0;
Hb = 47000.0;
} else if (h>=51000 && h<71000){
Pb = 66.9389;
Tb = 270.65;
Lb = -0.0028;
Hb = 51000.0;
} else if (h>=71000){
Pb = 3.95642;
Tb = 214.65;
Lb = -0.002;
Hb = 71000.0;
}
double exp = ((-g0 * M * (h-Hb))/R * Tb);
double press = Pb*Math.exp(exp);
JOptionPane.showMessageDialog(null, "The answer is " +press+ans+"Pascals", "Barometric Formula", JOptionPane.PLAIN_MESSAGE);
}
}
So what is wrong with this code?
The error message is telling you exactly what's wrong: You don't initialize all the local variables before use. So do it. When you declare your variables give them a default value.
class Foo {
public static void main(String[] args) {
int foo = 0; // initialized local variable
}
}
Set Pb, Tb, Lb, and Hb to 0 when they're declared so you have a default.
You know your code will never get an input for h that will let them not get set, but the compiler doesn't. It's worried they might never get set!
Because Pb, Tb, Lb, Hb are only initialised inside if blocks, it's possible that all the 'if' conditions will never arise, and so they'll come out the if blocks without being assigned a value. A final 'else' could help there, or giving them values before the block of conditionals.
More detailed: This branch of your multiple-case-branching is the culprit:
if (h<0){
ans = "error";
}
If this occurs, the variables Pb, Tb, Lb, Hb are not initialized, yet you still are using them in the showMessageDialog. So it should be enough to put initializations in this case:
if (h<0){
ans = "error";
Pb = 0;
Tb = 0;
Lb = 0;
Hb = 0;
}
A better way would be to throw an exception here (and catch it later), but if you didn't yet learn about exceptions, do it first the simple way.
Unrelated to your current problem, but your program could be written quite nicer without the long "if-then-else-if-..." statement using arrays like this:
// minima of the intervals
double[] Hbs = { 0.0, 11000.0, 20000.0, 32000.0, 47000.0, 51000.0, 71000.0 };
// parameters for each interval
double[] Pbs = {101325.0, 22632.1, 5474.89, 868.019, 110.906, 66.9389, 3.95642 };
double[] Tbs = { 288.15, 216.65, 216.65, 228.65, 270.65, 270.65, 214.65 };
double[] Lbs = { -0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002 };
int h = ...
if(h < 0) {
JOptionPane.showMessageDialog(null, "Don't use negative heights! (like " + h + ")", JOprionPane.ERROR_MESSAGE);
return;
}
// find out in which interval is our height
int i = Hbs.length-1;
while(h < Hbs[i]) {
i--;
}
double Hb = Hbs[i], Pb = Pbs[i], Tb = Tbs[i], Lb = Lbs[i];
double exp = ((-g0 * M * (h-Hb))/R * Tb);
double press = Pb*Math.exp(exp);
JOptionPane.showMessageDialog(null, "The answer is " +press+" Pascals", "Barometric Formula", JOptionPane.PLAIN_MESSAGE);
This avoids the uninitialized variable problem by returning early in case of an error.
double Pb, Tb, Lb, Hb;
change to
double Pb =0.0, Tb = 0.0, Lb = 0.0, Hb
= 0.0;

Categories

Resources