I posted this question earlier but not with the code in its entirety. The coe below also calls to other classes Background and Hydro which I have included at the bottom.
I have a Nullpointerexception at the line indicate by asterisks. Which would suggest to me that the Collections are not storing data properly. Although when I check their size they seem correct.
Thanks in advance. PS: If anyone would like to give me advice on how best to format my code to make it readable, it would be appreciated.
Elliott
>package exam0607;
>import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collection;
import java.util.Scanner;
import java.util.Vector;
>import exam0607.Hydro;
import exam0607.Background;// this may not be necessary???? FIND OUT
>public class HydroAnalysis {
public static void main(String[] args) {
Collection<Hydro> hydroList = null;
Collection<Background> backList = null;
try{hydroList = readHydro("http://www.hep.ucl.ac.uk/undergrad/3459/exam_data/2006-07/final/hd_data.dat");}
catch (IOException e){
e.getMessage();}
try{backList = readBackground("http://www.hep.ucl.ac.uk/undergrad/3459/exam_data/2006-07/final/hd_bgd.dat");
//System.out.println(backList.size());
}
catch (IOException e){
e.getMessage();}
for(int i =0; i <=14; i++ ){
String nameroot = "HJK";
String middle = Integer.toString(i);
String hydroName = nameroot + middle + "X";
System.out.println(hydroName);
ALGO_1(hydroName, backList, hydroList);
}
}
public static Collection<Hydro> readHydro(String url) throws IOException {
URL u = new URL(url);
InputStream is = u.openStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader b = new BufferedReader(isr);
String line ="";
Collection<Hydro> data = new Vector<Hydro>();
while((line = b.readLine())!= null){
Scanner s = new Scanner(line);
String name = s.next();
System.out.println(name);
double starttime = Double.parseDouble(s.next());
System.out.println(+starttime);
double increment = Double.parseDouble(s.next());
System.out.println(+increment);
double p = 0;
double nterms = 0;
while(s.hasNextDouble()){
p = Double.parseDouble(s.next());
System.out.println(+p);
nterms++;
System.out.println(+nterms);
}
Hydro SAMP = new Hydro(name, starttime, increment, p);
data.add(SAMP);
}
return data;
}
public static Collection<Background> readBackground(String url) throws IOException {
URL u = new URL(url);
InputStream is = u.openStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader b = new BufferedReader(isr);
String line ="";
Vector<Background> data = new Vector<Background>();
while((line = b.readLine())!= null){
Scanner s = new Scanner(line);
String name = s.next();
//System.out.println(name);
double starttime = Double.parseDouble(s.next());
//System.out.println(starttime);
double increment = Double.parseDouble(s.next());
//System.out.println(increment);
double sum = 0;
double p = 0;
double nterms = 0;
while((s.hasNextDouble())){
p = Double.parseDouble(s.next());
//System.out.println(p);
nterms++;
sum += p;
}
double pbmean = sum/nterms;
Background SAMP = new Background(name, starttime, increment, pbmean);
//System.out.println(SAMP);
data.add(SAMP);
}
return data;
}
public static void ALGO_1(String hydroName, Collection<Background> backgs, Collection<Hydro> hydros){
//double aMin = Double.POSITIVE_INFINITY;
//double sum = 0;
double intensity = 0;
double numberPN_SIG = 0;
double POSITIVE_PN_SIG =0;
//int numberOfRays = 0;
for(Hydro hd: hydros){
System.out.println(hd.H_NAME);
for(Background back : backgs){
System.out.println(back.H_NAME);
if(back.H_NAME.equals(hydroName)){//ERROR HERE
double PN_SIG = Math.max(0.0, hd.PN - back.PBMEAN);
numberPN_SIG ++;
if(PN_SIG > 0){
intensity += PN_SIG;
POSITIVE_PN_SIG ++;
}
}
}
double positive_fraction = POSITIVE_PN_SIG/numberPN_SIG;
if(positive_fraction < 0.5){
System.out.println( hydroName + "is faulty" );
}
else{System.out.println(hydroName + "is not faulty");}
System.out.println(hydroName + "has instensity" + intensity);
}
}
}
THE BACKGROUND CLASS
package exam0607;
public class Background {
String H_NAME;
double T_START;
double DT;
double PBMEAN;
public Background(String name, double starttime, double increment, double pbmean) {
name = H_NAME;
starttime = T_START;
increment = DT;
pbmean = PBMEAN;
}}
AND THE HYDRO CLASS
public class Hydro {
String H_NAME;
double T_START;
double DT;
double PN;
public double n;
public Hydro(String name, double starttime, double increment, double p) {
name = H_NAME;
starttime = T_START;
increment = DT;
p = PN;
}
}
Ah. Your Hydro class is completely wrong. You're assigning the parameters to the uninitialised members.
e.g.
public Hydro(String name, double starttime, double increment, double p) {
name = H_NAME;
but H_NAME is uninitialised. You need to reverse these e.g.
public Hydro(String name, double starttime, double increment, double p) {
H_NAME = name;
Some hints:
write a toString() method for each class, so you can print it out meaningfully
declare your method parameters as final if you don't expect them to change
declare your member variables to be final if you expect your class to be immutable (unchanging)
investigate unit tests and JUnit
In the above, 1. makes debugging easier 2. and 3. means that the compiler will prevent you from the (all too common) mistake above (try preceeding your method parameters with final and see what happens!) 4. will force you to test at a low level and keep your code correct.
For debugging purposes it's useful to only deference one reference at a time. This helps you identify unexpected null references e.g. if the following gives a NullPointerException
a.getB().getC().getD()
which of a, getB(), getC() gave the null reference ? Dereferencing one per line is more verbose but will give you much more info (object purists will object to the above and refer you to the Law Of Demeter - I shall ignore that for this example).
Related
I am building a math game for Android using Java. It includes a 3x3 grid of numbers that the user has to solve using mathematical operations. Before the start of the game, three random numbers 1-6 are rolled.
However, during my testing, I have discovered that some of the numbers are not solvable, say 4, with 1, 1, 1. (These numbers would never be rolled, but you get the point.)
I am using MxParser to find if the generated equation is correct, but the help I need is on how to create valid math equations.
I have decided to take the brute-force approach, but I am unsure as how to create valid mathematical equations with that method. It would have to generate equations like:
(Our numbers are: 1, 2, 3)
12^03^0 = 1 (True) Next number #1
12^03^0 = 2 (True) Next number #2
12^23^2 = 13 (False) Try again. #3
And so on.
I have tried brute-forcing already, but am unsure exactly how to do so.
`
import org.mariuszgromada.math.mxparser.Expression;
import java.util.ArrayList;
public class GridParser {
public String num1String = "";
public String num2String = "";
public String num3String = "";
private static String l;
private static String q;
private static String a;
private static int p;
private static char[] w;
private static char[] c;
public void parseGrid(int num1, int num2, int num3, int gridID) {
num1String = String.valueOf(num1);
num2String = String.valueOf(num2);
num3String = String.valueOf(num3);
String operator1 = "+";
String operator2 = "-";
String operator3 = "/";
String operator4 = "*";
String operator5 = "^";
ArrayList solutions3x3 = new ArrayList();
ArrayList solutions4x4 = new ArrayList();
ArrayList solutions6x6 = new ArrayList();
String currentSolution = "";
double NumberOnGrid = 0.0;
int currentPOS = 0;
if (gridID == 3) {
NumberOnGrid = 3.0;
String l = "1234567890-()=+√*/^";
q = "";
p = 0;
w = a.toCharArray();
c = l.toCharArray();
while (!q.equals(a)) {
for (int i = 0; i < l.length(); i++) {
System.out.println("[❕] Trying: " + c[i]);
if (c[i] == w[p]) {
q += c[i];
p++;
System.out.println("[✔️] Found: " + c[i]);
Expression targetExpression = new Expression(q);
double expressonResult = targetExpression.calculate();
if(expressonResult == NumberOnGrid){
}
}
if (q.equals(a)) {
System.out.println("\n[✔️] Equation Found!");
}
}
}
}
}
}
I apologize for my code, it is still in "Rough Draft" state. =)
Additionally, it would be great if this could run on a background thread so it would not slow down my Android app.
Thanks
Someone PLZZZ help!
The goal of the application is as following: I want to create objects (airplanes) of the class "Flugzeug" (German word for airplane). I want to create an array which refers to the different attributes of the objects.
The problem is (as far as I know) that one single array can only refer to variables of the exact same type.
How can I change my program that it works? Is it inevitable to create an array for each attribute (e.g. for each different type of variable)?
The code:
public class Fluggesellschaft {
public static void main(String[] args) {
Flugzeug [] airline = new Flugzeug [4];
for (int i = 0; i < 4; i=i+1){
airline[i] = new Flugzeug ();
airline[0].type = "A320";
airline[0].idNumber = "1";
airline[0].seats = "165";
airline[0].velocity = "890";
airline[0].range = "12600";
airline[1].type = "Boeing 747";
airline[1].idNumber = "2";
airline[1].seats = "416";
airline[1].velocity = "907";
airline[1].range = "12700";
airline[2].type = "Avro RJ 85";
airline[2].idNumber = "3";
airline[2].seats = "93";
airline[2].velocity = "760";
airline[2].range = "2200";
airline[3].type = "Airbus 380";
airline[3].idNumber = "4";
airline[3].seats = "516";
airline[3].velocity = "907";
airline[3].range = "12000";
}
for (int i=0; i < 4; i=i+1) {
airline[i].printInfo();
double time = airline[i].getTime(6320); //distance from Zurich to New York
System.out.println("duration: " + time + " h");
int capacity = airline[i].getCapacity(365);
System.out.println("capacity: " + capacity + " passengers / year");
}
}
}
public class Flugzeug {
String type;
int idNumber;
int seats;
double velocity;
double range;
double distance;
int days;
public void printInfo() {
System.out.println("type: " + this.type);
System.out.println("ID-number: " +this.idNumber);
System.out.println("seats: " + this.seats);
System.out.println("velocity: " + this.velocity);
System.out.println("range: " + this.range);
}
public double getTime (double dist) {
double result = 0;
result = dist / velocity;
double time = result;
return time;
}
public int getCapacity(int days) {
int capacity = seats * days;
return capacity;
}
}
The core of your problem is this:
one single array can only refer to variables of the exact same type.
That is correct (or mostly correct, all elements of an array must have a common base type, but that's not a relevant distinction right now).
But the type inside of your array is Flugzeug, not String!
So each element of the array must be a Flugzeug. That doesn't mean that the fields of that class have to all share a single type (and indeed, as you posted, they don't).
Look at this line:
airline[0].idNumber = "1";
this is almost correct, but since idNumber is an int you must assign it an int value (such as 1) instead:
airline[0].idNumber = 1;
The second (mostly unrelated) problem is that you try to access all 4 Flugzeug instances inside of the loop that creates them. That means when you try to access the second instance after just having created the first one (only!) it will crash:
Replace this:
for (int i = 0; i < 4; i=i+1) {
airline[i] = new Flugzeug ();
airline[0].type = "A320";
airline[1].type = "Boeing 747";
airline[2].type = "Avro RJ 85";
airline[3].type = "Airbus 380";
}
with this:
for (int i = 0; i < 4; i=i+1) {
airline[i] = new Flugzeug ();
}
airline[0].type = "A320";
airline[1].type = "Boeing 747";
airline[2].type = "Avro RJ 85";
airline[3].type = "Airbus 380";
if some type like int,double,long... was used " " ,They almost all become String type
I found two problems with your code.
First, you have declared idNumber as int int idNumber; but while assigning the value you are inserting a string value airline[0].idNumber = "1";.
NOTE: "1" is a string not integer.
The solution here would be airline[0].idNumber = 1;
You need to assign same type of values to every variable as they are declared.
And second, you are creating multiple objects in the loop airline[i] = new Flugzeug (); but overwriting the same single object (stored in the 0th position of the array) everytime. I would suggest to do,
airline[i].type = "A320";
airline[i].idNumber = 1; // Again this should not be "1"
airline[i].seats = 165; // And this should not be "165"
airline[i].velocity = 890; // Same is applicable here
airline[i].range = 12600; // and here
The problem is the variables are not only String type but ints and doubles as well. You need to assign the correct type. In addition you shouldn't access class variables like that, make them private create a constructor with getters and setters.
public class Flugzeug {
private String type;
private int idNumber;
private int seats;
private double velocity;
private double range;
private double distance;
private int days;
public Flugzeug(String type, int idNumber, int seats, double velocity, double range) {
this.type = type;
this.idNumber = idNumber;
this.seats = seats;
this.velocity = velocity;
this.range = range;
}
public double getDistance() {
return this.distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
}
public class Fluggesellschaft {
public static void main(String[] args) {
Flugzeug[] airline = new Flugzeug [4];
airline[0] = new Flugzeug("A320", 1, 165, 890, 12600);
airline[1] = new Flugzeug(...);
}
}
the tour length of www.math.uwaterloo.ca/tsp/data/ml/tour/monalisa_5757191.tour is supposed to be 5757191 yet my code gives a result of 5759929.877458311. Assuming that the claim of being willing to pay $1000 for any improvement to be true, then the below code MUST be wrong, and yet I see no flaw. At first I assumed it was a numerical precision issue so I started using arbitrary precision arithmetic and I got almost the same results.
- double: 5759929.877458459
- BigDecimal(precision: 8 digits): 5759756.8
- BigDecimal(precision: 16 digits): 5759929.877458103
- BigDecimal(precision: 32 digits): 5759929.877458311
- BigDecimal(precision: 64,128,256,512 digits): no change
all of these are WAY OFF from the stated 5757191.
I even removed the cyclic edge from the beginning to the end on the assumption that it was a TSP path instead of a cycle, but it is still way to high.
The datafile clearly states "EDGE_WEIGHT_TYPE: EUC_2D" so it's not a matter of it being a different distance metric... (i.e. euclidean metric (i.e. sqrt(sum of squares)))
Here is the dataset of the points
in this format
nodeId integerCoordinate1 integerCoordinate2
Here is the code that reads thoses files and only returns the given tour length:
import java.util.HashMap;
import java.util.ArrayList;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
public class TSPTest {
//map from NodeId from the input mona-lisa100K.tsp file to it's 2d coordinates
HashMap<Integer,int[]> pointMap;
//the order of NodeId's visited in a tour (first in the order of `mona-lisa100K.tsp' then replaced with the NodeId's in the best known 'monalisa_5757191.tour' file)
ArrayList<Integer> initState = new ArrayList<Integer>();
File file;
File tour;
int dimension;//i.e. 2 in this case
public TSPTest(File file, File tour) throws FileNotFoundException,IOException {
this.file = file;
this.tour = tour;
readFromFile();
loadTour();
}
public static void main(String... args) throws Throwable {
TSPTest tester = new TSPTest(new File("mona-lisa100K.tsp"),new File("monalisa_5757191.tour"));
int[] state = tester.initState();//the same values in 'monalisa_5757191.tour'
System.out.println("state.length: "+state.length);
double distance = tester.evaluate(state);
System.out.println("TOUR DISTANCE="+distance);
return;
}
synchronized void loadTour() throws FileNotFoundException,IOException {
if (tour == null) return;
BufferedReader in = new BufferedReader(new FileReader(tour), 1000000);
String line;
Pattern pLine = Pattern.compile("^\\d+$");
initState.clear();
while ((line = in.readLine()) != null) {
Matcher matcher = pLine.matcher(line);
if (!matcher.find()) {continue;}
initState.add(Integer.valueOf(matcher.group()));
}
in.close();
return;
}
synchronized void readFromFile() throws FileNotFoundException,IOException {
pointMap = new HashMap<Integer, int[]>();
BufferedReader in = new BufferedReader(new FileReader(file), 1000000);
String line;
Pattern pLine = Pattern.compile("\\d+( \\d+(?:\\.\\d*)?|\\.\\d+)+");
Pattern p = Pattern.compile("\\d+(?:\\.\\d*)?|\\.\\d+");
while ((line = in.readLine()) != null) {
Matcher matcher = pLine.matcher(line);
if (!matcher.find()) {continue;}
matcher = p.matcher(line);
if (!matcher.find()) {continue;}
dimension = 0;
while (matcher.find()) {++dimension;}
Integer index;
int[] cords = new int[dimension];
matcher.reset();
matcher.find();
index = Integer.valueOf(matcher.group());
initState.add(index);
for (int i = 0; i < dimension; ++i) {
matcher.find();
cords[i] = Integer.parseInt(matcher.group());
if (Math.abs(Double.parseDouble(matcher.group())-cords[i])>0.00001) {
//I'm assuming all integer coordinates
throw new RuntimeException(line);
}
}
pointMap.put(index, cords);
}
in.close();
return;
}
public int[] initState() {
int[] state = new int[initState.size()];
for (int i = 0; i < state.length; ++i) {
state[i] = initState.get(i);
}
return state;
}
public double evaluate(int[] state) {
int[] p1;
int[] p2;
java.math.MathContext mc = new java.math.MathContext(512,java.math.RoundingMode.HALF_EVEN);
//double distance = 0.;
java.math.BigDecimal distance = BigDecimal.ZERO;
//get first point in TSP tour
p1=pointMap.get(state[0]);
for (int i = 1; i<state.length; ++i) {
p2=pointMap.get(state[i]);//get the next point
//distance += distance(p1,p2,null);
distance = distance.add(distance(p1,p2,mc), mc);
p1=p2;//next point is now the first point
}
//next two lines would make it a distance over a TSP cycle instead of a path
//p2=pointMap.get(state[0]);
//distance += distance(p1,p2);
//return distance;
return distance.doubleValue();
}
//commented out double version of code that is replaced with BigDecimal
//private double distance(int[] p1, int[] p2, MathContext mc2) {
private BigDecimal distance(int[] p1, int[] p2, MathContext mc2) {
/*//old double based code
double distance = 0;
for (int i = 0; i < p1.length; ++i) {
distance += Math.pow(p1[i]-p2[i],2);
}
distance = Math.sqrt(distance);
return distance;
*/
//I thought this might improve precision... (no difference)
//return Math.hypot(p1[0]-p2[0],p1[1]-p2[1]);
//+8 just to be safe :)
MathContext mc = new MathContext(mc2.getPrecision()+8, java.math.RoundingMode.HALF_EVEN);
//euclidean distance
return sqrt(new BigDecimal(p1[0],mc).subtract(new BigDecimal(p2[0],mc)).pow(2,mc).add(new BigDecimal(p1[1],mc).subtract(new BigDecimal(p2[1],mc)).pow(2,mc)), mc);
}
//Babylonian method (aka Hero's method) (Newton's method)
private java.math.BigDecimal sqrt(java.math.BigDecimal A, java.math.MathContext mc2) {
MathContext mc = new MathContext(mc2.getPrecision()+8, java.math.RoundingMode.HALF_EVEN);
BigDecimal TWO = new BigDecimal(2);
BigDecimal x0 = new BigDecimal("0");
BigDecimal x1 = new BigDecimal(Math.sqrt(A.doubleValue()));
BigDecimal xp = null;
while (!x0.equals(x1) && (xp==null || x1.compareTo(xp)!=0)) {//xp is used to detect a convergence loop (x1 swaps with x0 in an infinite loop)
xp = x0;
x0 = x1;
x1 = A.divide(x0,mc);
x1 = x1.add(x0,mc);
x1 = x1.divide(TWO,mc);
}
return x1;
}
}
Okay so the program I'm working on needs to create an arrayList of change objects minimum of 1,000 and then compute the change that would be produced from that amount kind of like in a point of sale environment. I have everything working except I'm stumped on how to actually calculate the change. I have methods written in another class to do it, but I'm not sure how to pass the entire arrayList over to them in order to do so. If anyone could give me a hand with this it would be much appreciated.
Change class :
public class Change {
private double amount, remainingAmount;
private int occurences;
public Change() {
super();
this.amount = 17.87;
this.remainingAmount = (int)(amount * 100);
}
public Change(double amount, double remainingAmount) {
super();
this.amount = amount;
this.remainingAmount = remainingAmount;
}
public Change(float nextChange) {
this.amount = amount;
this.remainingAmount = remainingAmount;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public double getRemainingAmount() {
return remainingAmount;
}
public void incrementOccurence() {
occurences++;
}
public void setRemainingAmount(double remainingAmount) {
this.remainingAmount = remainingAmount;
}
public double numberOfOneDollars() {
int numberOfOneDollars = (int) (remainingAmount / 100);
remainingAmount = remainingAmount % 100;
return numberOfOneDollars;
}
public double numberOfQuarters() {
int numberOfQuarters = (int) (remainingAmount / 25);
remainingAmount = remainingAmount % 25;
return numberOfQuarters;
}
public double numberOfDimes() {
int numberOfDimes = (int) (remainingAmount / 10);
remainingAmount = remainingAmount % 10;
return numberOfDimes;
}
public double numberOfNickels() {
int numberOfNickels = (int) (remainingAmount / 5);
remainingAmount = remainingAmount % 5;
return numberOfNickels;
}
public int numberOfPennies() {
int numberOfPennies = (int) remainingAmount;
return numberOfPennies;
}
#Override
public String toString() {
return "Change [amount=" + amount + ", remainingAmount="
+ remainingAmount + "]\n";
}
}
Change ArrayList Class:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
public class ChangeArrayList {
private ArrayList<Change> changeArray = new ArrayList<Change>();
private static int numOfChangeObjects = 1000;
private static String FILE_NAME = "changeData.dat";
public static void makeChangeData() {
PrintWriter outputStream = null;
try
{
outputStream = new PrintWriter(FILE_NAME);
}
catch(FileNotFoundException e) {
System.out.println("Error opening the file " + FILE_NAME);
System.exit(0);
}
for (int count = 0; count < numOfChangeObjects; count++) {
//get random number between 0-1, move decimal right two places, typecast to float
//to get rid of decimals, then divide by 10.0 to get decimal left one place
//then add 3 to make sure numbers are >3
DecimalFormat df = new DecimalFormat("#.##");
double changeData = (float)(Math.random() * 100)/10.0 + 3;
double twoDecimal = Double.valueOf(df.format(changeData));
outputStream.println(twoDecimal + " ");
}
outputStream.close();
System.out.println("Those lines were written to " + FILE_NAME);
}
public void makeChangeArray(String fileName) {
changeArray = new ArrayList<Change>();
Scanner inputStream = null;
try
{
inputStream = new Scanner(new File(FILE_NAME));
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file " +
FILE_NAME);
System.exit(0);
}
while (inputStream.hasNext())
{
//read in a change object from the file
float nextChange = inputStream.nextFloat();
//Stuck here. Can't figure out what to put in to make this work
//everything else works except this. My change keeps coming out as 0
changeArray.add(new Change(nextChange));
//Stuck here. Can't figure out what to put in to make this work
//everything else works except this. My change keeps coming out as 0
}
inputStream.close();
}
public void writeToFile() {
String fileName = "out.txt"; //The name could be read from
//the keyboard.
PrintWriter outputStream = null;
try
{
outputStream = new PrintWriter(fileName);
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file " +
fileName);
System.exit(0);
}
outputStream.println(toString());
outputStream.close( );
System.out.println("Those lines were written to " +
fileName);
}
public String toString() {
String s = "";
for (int i = 0; i < changeArray.size(); i++) {
s += changeArray.get(i).toString(); }
return s;
}
public static void main(String[] args) {
ChangeArrayList.makeChangeData();
ChangeArrayList tester = new ChangeArrayList();
tester.makeChangeArray("changeData.dat");
//Something should go here to calculate change
//Not sure how to go about doing this
tester.writeToFile();
}
}
Approach 1:
You can make getter method for changeArray in ChangeArrayList. And after calling makeChangeArray() method in main method, you can call getter method and pass that returned arraylist to required method as a parameter.
Approach 2: I wll prefer this approach.
Do not declare class level changeArray, instead declare it inside your makeChangeArray() method and change return type to List instead of void and return the prepared arraylist.
I have a list of values (Weather data), the people who wrote the list used the value "9999" when they did not have a value to report. I imported the text file and used the following code to take the data, and edit it:
import java.io.*;
import java.util.*;
public class weatherData {
public static void main(String[] args)
throws FileNotFoundException{
Scanner input = new Scanner(new File("PortlandWeather2011.txt"));
processData(input);
}
public static void processData (Scanner stats){
String head = stats.nextLine();
String head2 = stats.nextLine();
System.out.println(head);
System.out.println(head2);
while(stats.hasNextLine()){
String dataLine = stats.nextLine();
Scanner dataScan = new Scanner(dataLine);
String station = null;
String date = null;
double prcp = 0;
double snow = 0;
double snwd = 0;
double tmax = 0;
double tmin = 0;
while(dataScan.hasNext()){
station = dataScan.next();
date = dataScan.next();
prcp = dataScan.nextInt();
snow = dataScan.nextInt();
snwd = dataScan.nextInt();
tmax = dataScan.nextInt();
tmin = dataScan.nextInt();
System.out.printf("%17s %10s %8.1f %8.1f %8.1f %8.1f %8.1f \n", station, date(date), prcp(prcp), inch(snow), inch(snwd), temp(tmax), temp(tmin));
}
}
}
public static String date(String theDate){
String dateData = theDate;
String a = dateData.substring(4,6);
String b = dateData.substring(6,8);
String c = dateData.substring(0,4);
String finalDate = a + "/" + b + "/" + c;
return finalDate;
}
public static double prcp(double thePrcp){
double a = (thePrcp * 0.1) / 25.4;
return a;
}
public static double inch(double theInch){
double a = theInch / 25.4;
if(theInch == 9999){
a = 9999;
}
return a;
}
public static double temp(double theTemp){
double a = ((0.10 * theTemp) * 9/5 + 32);
return a;
}
}
The problem I am having is taking the values and checking for all times "9999" comes up, and printing out "----". I don't know how to take in a value of type double, and print out a String.
This code takes the values and checks for the value 9999, and does nothing with it. This is where my problem is:
public static double inch(double theInch){
double a = theInch / 25.4;
if(theInch == 9999){
a = "----";
}
return a;
}
I'm sorry if I put to much information into this question. If you need me to clarify just ask. Thanks for any help!
You need to modify your inch function to return a string, not a double.
public static String inch(double theInch){
if(theInch == 9999){
return "----";
}
return Double.toString(theInch/25.4);
}
I think the first problem might be that you're reading all the values from the Scanner as int instead of doubles. For example, based on your System.out.println() statement, I think you should actually be reading the following data types...
prcp = dataScan.nextDouble();
snow = dataScan.nextDouble();
snwd = dataScan.nextDouble();
tmax = dataScan.nextDouble();
tmin = dataScan.nextDouble();
Also, seeing as though the inch() method is only going to be used in the System.out.println() line, you'll need to change it to a String as the return type...
public String inch(double theInch){
if (theInch == 9999){
return "----";
}
return ""+(theInch/25.4);
}