So, this is my question that I have to answer:
In the Payroll class, add a method with the header private int
computePay(Programmer p). The method should return the programmer’s
grade multiplied by the number of hours they worked. For example, if
the programmer’s grade is 2, and the total hours they worked is 6, the
method should return 12.
But my question for this forum is, how do I get a txt. file which contains Firstname Secondname,paygrade(Out of 3),hours,hours,hours,hours,hours,hours
(txt. example;
Sean Dyke,3,34,54,67,78,34,12
Fred Flintsone,1,65,78,89,89,34,23
Scooby Doo,2,54,56,67,87,89,65
)
To make the grade part separate to the hours they work, so I can then use
private int computePay(Programmer p){
return p.grade*p.hours;
}
I may have confused myself in this one, or thinking backwards, but any sort of guidelines would help.
I think the grade is after the name so you can split the array and take the values.
String[] temp = array1.split(",");
temp[0] gives name
temp[1] gives grade
temp[2...] gives hours worked
Well there are 2 ways of storing data in a .txt file:
You can put your object into an object stream and simply write that into a textfile.
FileOutputStream out = new FileOutputStream("test.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
// write something in the file
oout.writeObject(s);
// close the stream
oout.close();
Sadly the formating would be really bad and you could not read data on your own. Also that method is really inconsistent. You would need your class to implement Serializable. Furthmore, any change in your java code would stop making it possible to read that file.
So I would go for an attampt where you just store the name, followed by those hours. Then, read it line by line:
String s = "Sean Dyke,3,34,54,67,78,34,12"
String[] entries = s.split(",");
String name = entries[0];
Integer[] hours = new Integer[entries.length -1];
for(int i = 0; i < hours; i++){
hours[i] = Integer.parseInt(entries[i + 1]);
}
This could would parse one line. Do it for every line in your code txt file and you should be fine.
Related
I'm trying to solve a calculation problem in Java.
Suppose my data looks as follows:
466,2.0762
468,2.0799
470,2.083
472,2.0863
474,2.09
476,2.0939
478,2.098
It's a list of ordered pairs, in the form of [int],[double]. Each line in my file contains one pair. The file can contain seven to seven thousand of those lines, all of them formatted as plain text.
Each [int] must be subtracted from the [int] one line above and the result written onto another file. The same calculation must be done for every [double]. For example, in the data reported above, the calculation should be:
478-476 -> result to file
476-474 -> result to file
(...)
2.098-2.0939 -> result to file
2.0939-2.09 -> result to file
and so on.
I beg your pardon if this question will look trivial for the vast majority of you, but after weeks trying to solve it, I got nowhere. I also had troubles finding something even remotely similar on this board!
Any help will be appreciated.
Thanks!
Read the file
Build the result
Write to a file
For the 1. task there are already several good answers here, for example try this one: Reading a plain text file in Java.
You see, we are able to read a file line per line. You may build a List<String> by that which contains the lines of your file.
To the 2. task. Let's iterate through all lines and build the result, again a List<String>.
List<String> inputLines = ...
List<String> outputLines = new LinkedList<String>();
int lastInt = 0;
int lastDouble = 0;
boolean firstValue = true;
for (String line : inputLines) {
// Split by ",", then values[0] is the integer and values[1] the double
String[] values = line.split(",");
int currentInt = Integer.parseInt(values[0]);
double currentDouble = Double.parseDouble(values[1]);
if (firstValue) {
// Nothing to compare to on the first run
firstValue = false;
} else {
// Compare to last values and build the result
int diffInt = lastInt - currentInt;
double diffDouble = lastDouble - currentDouble;
String outputLine = diffInt + "," + diffDouble;
outputLines.add(outputLine);
}
// Current values become last values
lastInt = currentInt;
lastDouble = currentDouble;
}
For the 3. task there are again good solutions on SO. You need to iterate through outputLines and save each line in a file: How to create a file and write to a file in Java?
I've read gone through the tutorials, so by all means, if you see something that I've done wrong here, please tell me so I can learn to better-participate on this site.
The getPerishedPassengers method below is giving me an out of bounds exception. I have researched and researched, and I seem to be populating the array properly, and I don't know what is wrong with the method that I've created either. Could someone guide me in the right direction as to how to overcome this exception? Thank you folks!
Here's the main/method:
int passengerMax = 2000;
int passengerActual = 0;
//Create a 2D array that will store the data from the .txt file
String[][] passengerData = new String[passengerMax][6];
//Constructor to read the file and store the data in the array
Titanic(String file) throws FileNotFoundException {
try (Scanner fileIn = new Scanner(new File(file))) {
//Conditional for reading the data
while (fileIn.hasNextLine()) {
//tab through the data to read
passengerData[passengerActual++] = fileIn.nextLine().split("\t");
}
}
}
public int getTotalPassengers() {
return passengerActual;
}
//Method for getting/returning the number of passengers that perished
public int getPerishedPassengers() {
int count = 0;
//For loop w/conditional to determine which passengers perished
for (int i = 0; i < getTotalPassengers(); i++) {
int survive = Integer.parseInt(passengerData[i][1]);
/*The program reads the file and if 1, the passenger survived. If 0,
the passenger perished. Conditional will add to the count if they
survived*/
if (survive == 0) {
count++;
}
}
return count;
}
Here's the stacktrace I'm receiving. I can include the test code as well if you folks would like. Thanks in advance:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at titanic.Titanic.getPerishedPassengers(Titanic.java:66)
at titanic.testTitanic.main(testTitanic.java:68)
Java Result: 1
From what I can see above, the issue is in the line:
int survive = Integer.parseInt(passengerData[i][1]);
My best guess, lacking your input file, is that when you are reading the file, at least one line creates an array of length 0 or 1. In all likelihood, if the last line of the file is an empty line, it would be this line which is causing your array out of bounds exception, as the split would create an array of length 0. Another cause would be a line which lacks any tab in it at all (say a space instead of tabs, etc.) will create a length 1 array, of which passengerData[i][1] will not exist, only passengerData[i][0] will.
Assuming that your input file does not have any lines which are improperly formatted / lack the appropriate number of tabs, I would suggest changing this line in the file read loop:
passengerData[passengerActual++] = fileIn.nextLine().split("\t");
to:
String incomingLine = fileIn.nextLine().trim();
if (null != incomingLine && !incomingLine.isEmpty()) {
passengerData[passengerActual++] = incomingLine.split("\t");
}
this is a university assignment (sample academic report), I thought I was done and going to submit but when I started testing... I keep receiving ArrayIndexOutOfBoundsException on line 60 in main and I cannot see why. I am new to Java but really put a lot of hours into this program. Any help/advice is much appreciated.
line 60 = "int credits = Integer.parseInt(input[1]);" //im thinking error is something to due with data types??? im lost.
Course / Grade / Report classes pass data to the main java2pgm1
When you call split it returns you the an array. Here you are splitting using (":")
You need to check the length of variable input before accessing it.
String[] input = course.split(":");
int credits = Integer.parseInt(input[1]);
The input array may not contain more than 1 value so it fails
The exception will occur when the input from a user does not correspond to the expected format course_number:number_of_credits:grade_received:term_taken. In your case for what input value are you running into this exception? Does it contain a :?
Suggest that you test the length of the input array before referencing index[n]
String[] input = course.split(":");
int credits = Integer.parseInt(input[1]);
Integer term = Integer.parseInt(input[3]);
Course cObject = new Course(input[0],credits,input[2],input[3]);
The above snippet in your main always assumes that the course String has abc:def:ghi:jkl atleast 3 ":" in it. It is always good practice to handle the error case, when the string doesn't have 3 ":". Modify your code to something like below
String[] input = course.split(":");
if(input.length == 4)
{
int credits = Integer.parseInt(input[1]);
Integer term = Integer.parseInt(input[3]);
Course cObject = new Course(input[0],credits,input[2],input[3]);
}
else
{
//show some error message to user
}
here size of input array may be 0 or 1, you can check it by input.length.
If size of array is less or equal the element you want to get from array then runtime exception ArrayIndexOutOfBoundsException is thrown.
Im currently working on a program and any time i call Products[1] there is no null pointer error however, when i call Products[0] or Products[2] i get a null pointer error. However i am still getting 2 different outputs almost like there is a [0] and 1 or 1 and 2 in the array. Here is my code
FileReader file = new FileReader(location);
BufferedReader reader = new BufferedReader(file);
int numberOfLines = readLines();
String [] data = new String[numberOfLines];
Products = new Product[numberOfLines];
calc = new Calculator();
int prod_count = 0;
for(int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if(data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
System.out.println(Products[prod_count].getName());
BigDecimal price = new BigDecimal(data[2]);
Products[prod_count].setPrice(price);
for(String dataSt : data)
{
if(dataSt.toLowerCase().contains("imported"))
{
Products[prod_count].setImported(true);
}
else{
Products[prod_count].setImported(false);
}
}
calc.calculateTax(Products[prod_count]);
calc.calculateItemTotal(Products[prod_count]);
prod_count++;
This is the output :
imported box of chocolates
1.50
11.50
imported bottle of perfume
7.12
54.62
This print works System.out.println(Products[1].getProductTotal());
This becomes a null pointer System.out.println(Products[2].getProductTotal());
This also becomes a null pointer System.out.println(Products[0].getProductTotal());
You're skipping lines containing "input".
if(data[i].contains("input")) {
continue; // Products[i] will be null
}
Probably it would be better to make products an ArrayList, and add only the meaningful rows to it.
products should also start with lowercase to follow Java conventions. Types start with uppercase, parameters & variables start with lowercase. Not all Java coding conventions are perfect -- but this one's very useful.
The code is otherwise structured fine, but arrays are not a very flexible type to build from program logic (since the length has to be pre-determined, skipping requires you to keep track of the index, and it can't track the size as you build it).
Generally you should build List (ArrayList). Map (HashMap, LinkedHashMap, TreeMap) and Set (HashSet) can be useful too.
Second bug: as Bohemian says: in data[] you've confused the concepts of a list of all lines, and data[] being the tokens parsed/ split from a single line.
"data" is generally a meaningless term. Use meaningful terms/names & your programs are far less likely to have bugs in them.
You should probably just use tokens for the line tokens, not declare it outside/ before it is needed, and not try to index it by line -- because, quite simply, there should be absolutely no need to.
for(int i = 0; i < numberOfLines; i++) {
// we shouldn't need data[] for all lines, and we weren't using it as such.
String line = reader.readLine();
String[] tokens = line.split("(?<=\\d)\\s+|\\s+at\\s+");
//
if (tokens[0].equals("input")) { // unclear which you actually mean.
/* if (line.contains("input")) { */
continue;
}
When you offer sample input for a question, edit it into the body of the question so it's readable. Putting it in the comments, where it can't be read properly, is just wasting the time of people who are trying to help you.
Bug alert: You are overwriting data:
String [] data = new String[numberOfLines];
then in the loop:
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
So who knows how large it is - depends on the success of the split - but your code relies on it being numberOfLines long.
You need to use different indexes for the line number and the new product objects. If you have 20 lines but 5 of them are "input" then you only have 15 new product objects.
For example:
int prod_count = 0;
for (int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if (data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
// etc.
prod_count++; // last thing to do
}
I am trying to make a calculator for college gpa's. I cut out all like 20 if statements that just say what each letter grade is. I fixed my first program for anybody looking at this again. The program now works, but regardless of the letters i type in the gpa it returns is a 2.0 . If anybody sees anything wrong it would be very much appreciated...again. Thanks
import java.util.Scanner;
public class universityGPA {
public static void main(String args[]){
int classes = 4;
int units[] = {3, 2, 4, 4};
double[] grade = new double[4];
double[] value= new double[4];
int counter = 0;
double total = 0;
double gpa;
String letter;
while(classes > counter){
Scanner gradeObject = new Scanner(System.in);
letter = gradeObject.next();
if(letter.equalsIgnoreCase("A+") || letter.equalsIgnoreCase("A")){
grade[counter] = 4;
}
if(letter.equalsIgnoreCase("F")){
grade[counter] = 0;
}
value[counter] = grade[counter] * units[counter];
counter++;
}
for(int i = 0; i < classes; i++ ){
total += value[i];
}
gpa = total/classes;
System.out.println("You gpa is " +gpa);
}
}
You forgot to initialize grade. The NullPointerException is telling you that grade is null. The exception is thrown the first time you try to use grade, in the statment grade[counter] = 4;. Allocate as much space as you need with new.
Initialization of grade can be done statically as well dynamically:
double []grade = new double[4];
or
double []grade = new double[classes];
Do the same for value as well.
Here are a few pointers for cleaning up your code:
Try to be more consistent with your formatting. Make sure everything is properly indented and that you don't have lingering spaces at the beginnings or endings of lines (line 18).
You should declare variables as close to the first spot you use them as possible. This, along with making your code much more readable, minimizes the scope. For instance, on line 18, you initialize letter, but it is never used outside the scope of the while statement. You should declare the variable right there, along with the initializer (String letter = gradeObject.next()).
Declaring arrays in the type name[] form is discouraged. It is recommended to use the type[] name form instead.
Try to separate your program into distinguished sections. For instance, for this program, you can clearly see a few steps are involved. Namely, you first must grab some input, then parse it, then calculate the return value. These sections can be factored out into separate methods to clean up the code and promote reuse. While it may not seem to yield many benefits for such a simple program, once you start working on larger problems this organization will be absolutely mandatory.
NullPointerException means you are trying to access something that does not exist.
Since your grade[] is null, accessing it on line 21 by grade[counter] actually means you are accessing something that has yet to be created.
You need to initialize the array, so it actually has an instance.