Calculating the average grade from a file [duplicate] - java

This question already has answers here:
Reading only the integers from a txt file and adding the value up for each found
(5 answers)
Closed 5 years ago.
I'm working on a project that reads in grades from a file but the file contains student names and the class they are in as well, some have 3 grades and some have 4. I'm struggling with getting a divide by 0 error when I try to run the program and cant figure it out after much googling, beginner with java. I'm fine with opening the file but I'm struggling with how to get it to read the average of the first line then continue to all the other ones as well returning the value in the println.
File contents(with three grades):
//Happy CS145 81 85 91
//Sneezy CS145 67 75 75
//Doc CS145 92 97 89
//Dopey CS111
//Grumpy CS145 75 65 66
//Bashful CS145 81 82 81
//Sleepy CS145 71 74 71
import java.io.FileReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MainClass {
public static void main(String args[]){
int numTestScores = 0;
int sum = 0;
int average = 0;
Scanner input = null;
try {
input = new Scanner(new File("PA2data2.txt"));
} catch (FileNotFoundException ex) {
System.out.println("Cannot open file - " + ex);
}
while (input.hasNext()) {
while (input.hasNextInt()){
sum += input.nextInt();
numTestScores++;
}
average = sum / numTestScores;
System.out.println(average);
}
System.out.println("Average is " + sum / numTestScores);
input.close();
}
}

You should use nextLine() rather than nextInt()
while (input.hasNext()) {
String line = input.nextLine();
String[] brokenLine = line.split(" ");
//do stuff with your array of {Happy, CS145, 81, 85, 91}
...
...
}
Also, your also going to want to use doubles rather than int for average, you will get average of 0 otherwise.

Just keep your division operation inside an if statement:
if(numTestScores > 0) {
average = sum / numTestScores;
System.out.println(average);
}

Related

Java Loop Confusion

I wrote this code that was intended to read a file with integer values. If the integer values are >= 0 and <=100 I need to give the average of the grades. If there are any values out of the specified range 0-100 then I need to count the incorrect integer grades, inform the user of the incorrect grades, and inform how many incorrect grades there were. I attempted the code but I keep getting the error code:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at Project9.main(Project9.java:26)
Code sample:
public static void main(String[] args) throws IOException{
String file;
int readInts;
Scanner k = new Scanner(System.in);
System.out.println("Enter filename: ");
file = k.nextLine();
int counterWrong = 0;
int counterRight = 0;
int sum = 0;
double average = 1.0 * sum/counterRight;
File fileReader = new File(file);
if (fileReader.exists()) {
Scanner input = new Scanner(fileReader);
while (input.hasNext()) {
readInts = input.nextInt();
System.out.println(readInts);
String a = input.next();
int a2 = Integer.parseInt(a);
if (a2 <= 100 && a2 >= 0){
counterRight++;
sum = sum + a2;
System.out.println("Score " + a2 + " was counted.");
} else {
counterWrong++;
System.out.println("The test grade " + a2 + " was not scored as it was out of the range of valid scores.");
System.out.println("There were " + counterWrong + " invalid scores that were not counted.");
}
}
if (counterRight > 0){
System.out.println("The average of the correct grades on file is " + average + ".");
}
} else {
System.out.println("The file " + file + " does not exist. The program will now close.");
}
}
}
You are doing a single check hasNext but then you read twice from scanner using nextInt() and next().
There may be two issues with your code I see.
file = k.nextLine(); // Depending on how your file is set up k.nextLine() or k.next() or maybe k.nextInt() may be useful.
while (input.hasNext()) {
readInts = input.nextInt(); // input.hasNext() assumes the next value the scanner is reading has a string value which would make readInts = input.nextInt(); impossible to use without parsing (or some other method).
I thought it'd be fun to try out this exercise (didn't want to ruin it for you). Check out my code and hopefully you'll pick up on some of the concepts I was talking about.
Note: My program reads integer values like 95 185 23 13 90 93 37 125 172 99 54 148 53 36 181 127 85 122 195 45 79 14 19 88 34 73 92 97 200 167 126 48 109 38. Which uses hasNext() & next() to get every token listed. So using nextLine() wouldn't be useful for the given input.
package cs1410;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JFileChooser;
public class Grader {
public static void main(String[] args) throws IOException {
int count = 0;
int sum = 0;
double ave = 0;
int incorrectCount = 0;
String correctGrades = "";
String incorrectGrades = "";
// Read file input
JFileChooser chooser = new JFileChooser();
if (JFileChooser.APPROVE_OPTION != chooser.showOpenDialog(null)) {
return;
}
File file = chooser.getSelectedFile();
// Scan chosen document
Scanner s = new Scanner(file);
// While the document has an Int
while (s.hasNextInt()) {
// Convert our inputs into an int
int grade = Integer.parseInt(s.next());
if (grade >= 0 && grade <= 100) {
// adds sum
sum += grade;
// increments correct count
count++;
// displays valid grades
correctGrades += Integer.toString(grade) + "\n";
} else {
// increments incorrect count
incorrectCount++;
// displays invalid grades
incorrectGrades += Integer.toString(grade) + "\n";
}
}
// Created average variable
ave = sum / count;
// bada bing bada boom
System.out.println("The number of correct grades were " + correctGrades);
System.out.println("The average score on this test was " + ave + "\n");
System.out.println("The number of incorrect grades were " + incorrectCount + "\n");
System.out.println("The incorrect values for the grades were " + "\n" + incorrectGrades);
}
}
Use hasNextInt() instead of hasNext().
hasNext() only means there is another token, not necessarily that there is another integer which you are assuming when you wrote nextInt().
Here's the documentation for hasNext() and hasNextInt()
You also want to do a check before this line:
String a = input.next();

Every time i compile my project everything outside the while loop doesn't show up (input comes from file)

import java.io.*;
import java.util.*;
public class Statistics {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(new FileReader("C:\\Users\\user\\Desktop\\students.dat"));//Opened file
int math=0,spanish=0,french=0,english=0,count=0,sum,highSpan=0,highMath=0,highFren=0,highEng=0;//Declarations
double avg,highAvg=0;
String name,highName;
highName="";
name = ""; //Prime read
while (name!="ENDDATA"){ //Sentinel condition
count++; //Keeps count of students
name = in.next();
spanish=in.nextInt();
math=in.nextInt();
french=in.nextInt();
english=in.nextInt();
sum = spanish + math + french + english;
avg = sum/4; //Claculates Average
System.out.printf("%s - %.0f\n",name,avg);
if (avg > highAvg){ //Checks for the highest Average
highAvg = avg;
highName = name;
}
if (spanish > highSpan){
highSpan = spanish;
}
if (math > highMath){
highMath = math; //Checks for the highest mark for each subject
}
if (french > highFren){
highFren = french;
}
if (english > highEng){
highEng = english;
}
name = in.nextLine();
}
System.out.printf("Number of students in class is: %d\n",count);
System.out.printf("The highest student average is: %f\n",highAvg);
System.out.printf("The student who made the highest average is: %s\n",highName);
System.out.printf("The highest Spanish mark is: %d\n",highSpan);
System.out.printf("The highest Math mark is: %d\n",highMath);
System.out.printf("The highest French mark is: %d\n",highFren);
System.out.printf("The highest English mark is: %d\n",highEng);
in.close(); //Closing of file
}
}
Write a Java program to read and process each line of the textfile and print the following
information (for each line except the last):
The number of students in the class
The name and average score for each student
The highest student average in the class (ignore the possibility of a tie)
The name of the student who attained the highest average (ignore the possibility of a tie)
The highest mark for each subject
its supposed to read the data form a dat file and make the necessary output but the print statements outside the while loop are not showing up also i get this output with the error below.
MARY - 65
SHELLY - 70
JOHN - 60
ALFRED - 71
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Statistics.main(Statistics.java:17)
in.nextInt() is throwing NoSuchElementException.
Your File seems to have improper data.
Your while loop will never break because your condition:
while(name!="ENDDATA")
will always be true. That's why when all the token are exhausted the scanner object throws NoSuchElementException. And because of the exception your print statement after the while loops are not executed.
Try to use hasNext() method of scanner to check for the next token.
Replace your while loop with this while.
while (in.hasNext()){ //Sentinel condition
count++; //Keeps count of students
name = in.next();
if(name.equals("ENDDATA")){
break;
}
spanish=in.nextInt();
math=in.nextInt();
french=in.nextInt();
english=in.nextInt();
sum = spanish + math + french + english;
avg = sum/4; //Claculates Average
System.out.printf("%s - %.0f\n",name,avg);
if (avg > highAvg){ //Checks for the highest Average
highAvg = avg;
highName = name;
}
if (spanish > highSpan){
highSpan = spanish;
}
if (math > highMath){
highMath = math; //Checks for the highest mark for each subject
}
if (french > highFren){
highFren = french;
}
if (english > highEng){
highEng = english;
}
}
Students.dat file format should look like this:
Shelly 2 2 3 4
Brown 34 2 1 4
Pink 23 45 21 1
ENDDATA
Maybe it's because of name = in.next() and name = in.nextLine() in the while loop.I think one is enough.
For example:
name = in.next();
do{
.....
....
name = in.next();
}while(name!="ENDDATA");
The problem seems to be at the line french=in.nextInt(). As the documentation says, nextInt() will throw a NoSuchElementException when there is no more input to read.
public int nextInt()
Throws:
NoSuchElementException - if input is exhausted
Probably one of your entries in student.dat is not filled the way you expect it to be.

Printing out student averages with file input using string tokenizer and scanner

I am trying to get the averages of values in a text file. The content of the file is:
Agnes 56 82 95 100 68 52
Bufford 87 92 97 100 96 85 93 77 98 86
Julie 99 100 100 89 96 100 92 99 68
Alice 40 36 85 16 0 22 72
Bobby 100 98 92 86 88
I have to skip the names, and try to sum the values of the integers of each line. The ouput should be something like this:
Agnes, average = 76
Bufford, average = 91
Julie, average = 94
Alice, average = 39
Bobby, average = 93
My problem is that i am unable to sum the values (using sum+=sc1.nextInt()). I also cant count the number of tokens of just the integers. For example, for the first line I need countTokens to equal 6, but i get 7, even after I skip the name.
import java.io.*;
import java.util.*;
public class studentAverages
{
public static void main() throws IOException
{
Scanner sf = new Scanner(new File("C:\\temp_Name\\StudentScores.in"));
int maxIndex = -1;
String text[] = new String[100];
while(sf.hasNext( ))
{
maxIndex++;
text[maxIndex] = sf.nextLine();
}
sf.close();
int sum=0;
int avg=0;
int divisor=0;
for (int i=0;i<=maxIndex; i++)
{
StringTokenizer sc= new StringTokenizer(text[i]);
Scanner sc1= new Scanner (text[i]);
while (sc1.hasNext())
{
sc1.useDelimiter(" ");
sc1.skip("\\D*");
System.out.print(sc1.nextInt());
System.out.println(sc1.nextLine());
sum+=sc1.nextInt(); // trying to sum all the numbers in each line, tried putting this line everywhere
avg=sum/divisor;
break;
}
System.out.println(avg);
while (sc.hasMoreTokens())
{
divisor=sc.countTokens()-1; //Not able to count tokens of just the numbers, thats why I am using -1
//System.out.println(divisor);
break;
}
}
//this is for the output
/*for (int i=0; i<=maxIndex; i++)
{
String theNames="";
Scanner sc= new Scanner (text[i]);
theNames=sc.findInLine("\\w*");
System.out.println(theNames + ", average = ");
}*/
}
}
I would recommend splitting each line using the split method and then looping through those values while ignoring the first, because you know that is the title.
public static void main() throws IOException {
Scanner sf = new Scanner(new File("C:\\temp_Name\\StudentScores.in"));
int maxIndex = -1;
String text[] = new String[100];
while(sf.hasNext( )) {
maxIndex++;
text[maxIndex] = sf.nextLine();
}
sf.close();
for(int i = 0; i < maxIndex; i ++) {
String[] values = text[i].split(" ");
String title = values[0];
int sum = 0;
for(int j = 1; i < values.length; j ++) {
sum += Integer.parseInt(values[j]);
}
double average = sum / (values.length - 1);
System.out.println(title + ": " + average);
}
}
Notice that the inner loop's index begins at 1 and not 0, and that when calculating the average, we subtract one from the size of the values array because we want to ignore the title.
Try this one:
Scanner scanner = new Scanner(new File("resources/abc.txt"));
//check for next line
while (scanner.hasNextLine()) {
//create new scanner for each line to read string and integers
Scanner scanner1 = new Scanner(scanner.nextLine());
//read name
String name = scanner1.next();
double total = 0;
int count = 0;
//read all the integers
while (scanner1.hasNextInt()) {
total += scanner1.nextInt();
count++;
}
System.out.println(name + ", average = " + (total / count));
}
scanner.close();
output:
Agnes, average = 75.5
Bufford, average = 91.1
Julie, average = 93.66666666666667
Alice, average = 38.714285714285715
Bobby, average = 92.8
--EDIT--
Here is the code as per your last comment (I have to use StringTokenizer`/string methods like useDelimiter, skip, etc to arrive at the answer)
Scanner sf = new Scanner(new File("resources/abc.txt"));
List<String> text = new ArrayList<String>();
while (sf.hasNext()) {
text.add(sf.nextLine());
}
sf.close();
for (String str : text) {
StringTokenizer sc = new StringTokenizer(str, " ");
double sum = 0;
int count = 0;
String name = sc.nextToken();
while (sc.hasMoreElements()) {
sum += Integer.valueOf(sc.nextToken());
count++;
}
System.out.println(name + ", average = " + (sum / count));
}
}
output
Agnes, average = 75.5
Bufford, average = 91.1
Julie, average = 93.66666666666667
Alice, average = 38.714285714285715
Bobby, average = 92.8

Error when reading from text file

I keep getting this error when reading from a text file it gets the first few numbers but then does this there also shouldnt be 0's in there, tried a lot of things not sure what to do. I have to be able to read the file numbers and then multiply specific ones could use some help thanks. (I was using the final println to check what numbers it was getting). Sorry forgot the error is this output
4
32
0
38
0
38
0
16
0
Error: For input string: ""
Here is my file:
Unit One
4
32 8
38 6
38 6
16 7
Unit Two
0
Unit Three
2
36 7
36 7
Unit Four
6
32 6.5
32 6.5
36 6.5
36 6.5
38 6.5
38 6.5
Unit Five
4
32 6.5
32 8
32 7
32 8
Unit Six
5
38 7
30 6.5
24 8
24 8
24 8
Unit Seven
0
Unit Eight
1
40 12
Unit Nine
5
24 8
24 6.5
30 6.5
24 7
32 7
And here is my code:
package question;
import java.io.*;
import java.util.Scanner;
public class Weight
{
public static void main(String[] args)//main method
{
try
{
Scanner input = new Scanner(System.in);
//System.out.print("Please enter proposed weight of stock : ");
// int proposedWeight = input.nextInt();
File file = new File("MathUnits.txt");
System.out.println(file.getCanonicalPath());
FileInputStream ft = new FileInputStream(file);
DataInputStream in = new DataInputStream(ft);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strline;
while((strline = br.readLine()) != null)
{ int i = 0;
if (strline.contains("Unit"))
{
continue;
}
else {
String[] numstrs = strline.split("\\s+"); // split by white space
int[] nums = new int[numstrs.length];
nums[i] = Integer.parseInt(numstrs[i]);
for(int f = 0; f <numstrs.length; f++)
{
System.out.println(""+ nums[f]);
}
}
i ++;
}
//int x = Integer.parseInt(numstrs[0]);
// int m = Integer.parseInt(numstrs[1]);
// int b = Integer.parseInt(numstrs[2]);
// int a = Integer.parseInt(numstrs[3]);
int a = 0;
// System.out.println("this >>" + x + "," + m +"," + b + "," + a);
// if(proposedWeight < a)
// {
// System.out.println("Stock is lighter than proposed and can hold easily");
// System.exit(0);
// }
// else if ( a == proposedWeight)
// {
// System.out.println("Stock is equal to max");
// System.exit(0);
// }
// else
// {
// System.out.println("stock is too heavy");
// System.exit(0);
// }
in.close();
}
catch(Exception e)
{
System.err.println("Error: " + e.getMessage());
}
}
}
One probable error I see
You're not taking newlines into consideration, especially when you're doing a nums[i] = Integer.parseInt(numstrs[i]); on an empty string
Also, I don't think you're getting the numbers into the array correct since you're getting only one int from each line, when some lines have two

take data from a txt file into a 2D array

Thank you all very much for your help both answers work Perfectly.
I have a Lab assigment for Java that I need some help with please.
The assignemnt is to Read a txt that has 28 ints and then place them into a 2D Array.
Here is what I have:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TextFileExample {
public static void main(String[] args) {
String fileName = "TemperatureData.txt";
Scanner inputStream = null;
System.out.println("The file " + fileName + "\ncontains the following lines:\n");
try
{
inputStream = new Scanner(new File("C:\\Users\\username\\Documents\\TemperatureData.txt"));//The txt file is being read correctly.
String line = inputStream.nextLine();
String[] numbers = line.split("");
int[][] temperatures = new int[4][7];
for (int row = 0; row < 4; row++) {
for (int column = 0; column < 7; column++) {
temperatures[row][column] = temperatures.parseInt(temperatures[row][column]);//Is this correct?
}
}
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file " + fileName);
System.exit(0);
}
while (inputStream.hasNextLine())
{
String line = inputStream.nextLine();
System.out.println(line);
}
inputStream.close();
}
}
I need some help as to Getting the data from the txt file into the array temperatures[4][7].
Then printout the temperatures array showing the data. The output should be as follow:
Temperature Data
Week 1: 73 71 68 69 75 77 78
Week 2: 76 73 72 72 75 79 76
Week 3: 79 82 84 84 81 78 78
Week 4: 75 72 68 69 65 63 65
He does not required the txt file to be an output.
The txt file is this:
73
71
68
69
75
77
78
76
73
72
72
75
79
76
79
82
84
84
81
78
78
75
72
68
69
65
63
65
temperatures[row][column] = temperatures.parseInt(temperatures[row][column]);
Should be
temperatures[row][column] = Integer.parseInt(line);
Also, delete String[] numbers = line.split(""); as it is not used.
You need to reorder a few more things for this to work. The logic is:
Open file
if filenotfound, quit
loop through your arrays
Parse the string in the file, put it in your array
Now you can do something with the array. Note this does not elegantly handle the case where the file isn't long enough.
String fileName = "TemperatureData.txt";
Scanner inputStream = null;
System.out.println("The file " + fileName + "\ncontains the following lines:\n");
try
{
inputStream = new Scanner(new File("C:\\Users\\username\\Documents\\TemperatureData.txt"));//The txt file is being read correctly.
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file " + fileName);
System.exit(0);
}
for (int row = 0; row < 4; row++) {
for (int column = 0; column < 7; column++) {
String line = inputStream.nextLine();
int[][] temperatures = new int[4][7];
temperatures[row][column] = Integer.parseInt(line);
}
}
inputStream.close();
Here is a solution:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.StringTokenizer;
public class TxtTo2DArray {
public static void main(String[] args) throws FileNotFoundException, IOException {
String filename = ""; //Here you must write the path to the file f.exp "//folder//file.txt"
try{
FileReader readConnectionToFile = new FileReader(filename);
BufferedReader reads = new BufferedReader(readConnectionToFile);
Scanner scan = new Scanner(reads);
int[][] temperatures = new int[4][7];
int counter = 0;
try{
while(scan.hasNext() && counter < 5){
for(int i = 0; i < 4; i++){
counter = counter + 1;
for(int m = 0; m < 7; m++){
temperatures[i][m] = scan.nextInt();
}
}
}
for(int i = 0; i < 4; i++){
System.out.println("Temperature at week:" + (i + 1) + " is: " + temperatures[i][0] + ", " + temperatures[i][1] + ", " + temperatures[i][2] + ", " + temperatures[i][3] + ", " + temperatures[i][4] + ", " + temperatures[i][5] + ", " + temperatures[i][6]);
}
} catch(InputMismatchException e){
System.out.println("Error converting number");
}
scan.close();
reads.close();
} catch (FileNotFoundException e){
System.out.println("File not found" + filename);
} catch (IOException e){
System.out.println("IO-Error open/close of file" + filename);
}
}
}
With your file gave this results:
Temperature at week:1 is: 73, 71, 68, 69, 75, 77, 78
Temperature at week:2 is: 76, 73, 72, 72, 75, 79, 76
Temperature at week:3 is: 79, 82, 84, 84, 81, 78, 78
Temperature at week:4 is: 75, 72, 68, 69, 65, 63, 65

Categories

Resources