Weighted mean of a column in csv file in Java - java

I am trying to compute the number of elements in a column present in a CSV file using which I would like to compute the mean.
This is how I tried to find the length of the column, but it gives me the length of each data in the column. It's something very silly but I have been stuck with this for a long time.
public static void main(String[] args) throws Exception {
String splitBy = ";";
int x;
BufferedReader br = new BufferedReader(new FileReader("bank.csv"));
String line;
while ((line = br.readLine()) !=null) {
String[] b = line.split(splitBy);
x = b[10].length();
System.out.println("length " + x);
}
br.close();
}
This is the CSV file:
https://raw.githubusercontent.com/pandutruhandito/practice_bank_marketing_data/master/bank/bank-full.csv

You will want something like the following. A few notes.
If a value is always required then you can simply count the number of lines in the CSV to give you the number of values in the column. Otherwise you'll need to check if there is an actual value.
You were grabbing the month column, remember indexes start at 0.
public static void main(String[] args) throws Exception {
final String splitBy = ";";
int totalValue = 0;
int columnCount = 0;
final BufferedReader br = new BufferedReader(new FileReader("C:/test/bank-full.csv"));
String line;
// Throw away headers.
line = br.readLine();
while ((line = br.readLine()) != null)
{
String[] splitCSV = line.split(splitBy);
if (!splitCSV[9].equals(""))
{
totalValue += Integer.parseInt(splitCSV[9]);
columnCount++;
}
}
br.close();
System.out.println("Average is " + totalValue / columnCount);
}

b[10].length() is incorrect: it gives you the size of string of the 10th element in a particular line (and it changes in the loop)
line.length(): lengh of the line
b.length: number of elements in a line
if you want the number of columns, you can just only keep the number of lines read (just count your readlin())
Or you can also keep everything in a table.
beware: some csv have , or ; , and perhaps inside " (if there is string)

You have to use x = b.length; which will give you exact length per line.
public static void main(String[] args) throws Exception {
String splitBy = ";";
int x;
BufferedReader br = new BufferedReader(new FileReader("bank.csv"));
String line;
while ((line = br.readLine()) !=null) {
String[] b = line.split(splitBy);
x = b.length;
System.out.println("length " + x);
}
br.close();
}

Related

InputStream reading file and counting lines/words

I'm working on a project and I'm trying to count
1) The number of words.
2) The number of lines in a text file.
My problem is that I can't figure out how to detect when the file goes to the next line so I can increment lines correctly. Basically if next is not a space increment words and if next is a new line, increment lines. How would I do this? Thanks!
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNext()) {
if (f.next().equals("\n")) {
lines++;
} else if (!(f.next().equals(" "))) {
words++;
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Try this:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
lines++;
for (String token : line.split("\\s+")) {
if (!token.isEmpty()) {
words++;
}
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Do you have to use InputStream? (Yes) It is better to use a BufferedReader with an InputStreamReader passed in so you can read the file line by line and increment while doing so.
numLines = 0;
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null)
{
numLines++;
// process the line.
}
}
Then to count the words just split the string using a regular expression that finds whitespaces. myStringArray = MyString.Split(MyRegexPattern); will then return a String[] of all the words. Then all you do is numWords += myStringArray.length();
You can use an InputStreamReader to create a bufferedreader which can read a file line by line:
int amountOfLines = 0;
try {BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))} catch (Exception e) {e.printStackTrace();}
String line;
while ((line = br.readLine()) != null{
numLines++;
// process the line.
}
You can then use the split(String) method to separate every part
Try following:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
String[] arr = line.split("\\s");
words += arr.length;
lines++;
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}

Take values from a text file and put them in a array

For now in my program i am using hard-coded values, but i want it so that the user can use any text file and get the same result.
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
public class a1_12177903
{
public static void main(String [] args) throws IOException
{
if (args[0] == null)
{
System.out.println("File not found");
}
else
{
File file = new File(args[0]);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = "";
while (br.ready())
{
line += br.readLine();
}
String[] work = line.split(",");
double[] doubleArr = new double[work.length];
for (int i =0; i < doubleArr.length; i++)
{
doubleArr[i] = Double.parseDouble(work[i]);
}
double maxStartIndex=0;
double maxEndIndex=0;
double maxSum = 0;
double total = 0;
double maxStartIndexUntilNow = 0;
for (int currentIndex = 0; currentIndex < doubleArr.length; currentIndex++)
{
double eachArrayItem = doubleArr[currentIndex];
total += eachArrayItem;
if(total > maxSum)
{
maxSum = total;
maxStartIndex = maxStartIndexUntilNow;
maxEndIndex = currentIndex;
}
if (total < 0)
{
maxStartIndexUntilNow = currentIndex;
total = 0;
}
}
System.out.println("Max sum : "+ maxSum);
System.out.println("Max start index : "+ maxStartIndex);
System.out.println("Max end index : " +maxEndIndex);
}
}
}
I've fixed it so it takes in the name of the text file from the command line. if anyone has any ways to improve this, I'll happily accept any improvments.
You can do this with Java8 Streams, assuming each entry has it's own line
double[] doubleArr = Files.lines(pathToFile)
.mapToDouble(Double::valueOf)
.toArray();
If you were using this on production systems (rather than as an exercise) it would be worth while to create the Stream inside a Try with Resources block. This will make sure your input file is closed properly.
try(Stream<String> lines = Files.lines(path)){
doubleArr = stream.mapToDouble(Double::valueOf)
.toArray();
}
If you have a comma separated list, you will need to split them first and use a flatMap.
double[] doubleArr = Files.lines(pathToFile)
.flatMap(line->Stream.of(line.split(","))
.mapToDouble(Double::valueOf)
.toArray();
public static void main(String[] args) throws IOException {
String fileName = "";
File inputFile = new File(fileName);
BufferedReader br = new BufferedReader(new FileReader(inputFile));
// if input is in single line
StringTokenizer str = new StringTokenizer(br.readLine());
double[] intArr = new double[str.countTokens()];
for (int i = 0; i < str.countTokens(); i++) {
intArr[i] = Double.parseDouble(str.nextToken());
}
// if multiple lines in input file for a single case
String line = "";
ArrayList<Double> arryList = new ArrayList<>();
while ((line = br.readLine()) != null) {
// delimiter of your choice
for (String x : line.split(" ")) {
arryList.add(Double.parseDouble(x));
}
}
// convert arraylist to array or maybe process arrayList
}
This link may help: How to use BufferedReader. Then you will get a String containing the array.
Next you have several ways to analyze the string into an array.
Use JSONArray to parse it. For further information, search google for JSON.
Use the function split() to parse string to array. See below.
Code for way 2:
String line="10,20,50";//in fact you get this from file input.
String[] raw=line.split(",");
String[] arr=new String[raw.length];
for(int i=0;i<raw.length;++i)arr[i]=raw[i];
//now arr is what you want
Use streams if you are on JDK8. And please take care of design principles/patterns as well. It seems like a strategy/template design pattern can be applied here. I know, nobody here would ask you to focus on design guidelines.And also please take care of naming conventions. "File" as class name is not a good name.

Index out of bounds error when parsing to Integer

I am getting an error when trying to parse from a String to an Integer or a double.
int id = Integer.parseInt(stringParts[2]);
If I print stringParts[2] it works, it only throws an error when parsing.
This is the complete loop I'm using:
public static StudentRecord[] creates(String fileName) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("/Users/DNA40/Desktop/lab11input.txt"));
int lineText = lineCount("/Users/DNA40/Desktop/lab11input.txt");
String record;
String cons = ("[ ]");
StudentRecord[] student = new StudentRecord[lineText];
String[] stringParts = new String[5];
for(int i = 0; i < lineText ; i++){
student[i] = new StudentRecord();//Creates Object class
record = br.readLine(); //Stores the first line of text file
stringParts = record.split("\\s+");//Splits the line into parts
student[i].setFirstName(stringParts[0]);
student[i].setLastName(stringParts[1]);
int id = Integer.parseInt(stringParts[2]);
student[i].setID(id);
double gpa = Double.parseDouble(stringParts[3]);
student[i].setGPA(gpa);
int hours = Integer.parseInt(stringParts[4]);
student[i].setHours(hours);
}
return student;
}
public static int lineCount(String fileName) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
int count = 0;
String currentLine;
while ((currentLine = br.readLine()) != null){
count++;
}
return count;
}
It generates error: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
Thank you
Index out of bounds means that
stringParts[2]
does not exist. Check the length of the array. The split probably isent working as you would expect

Read first character on each line in a file

I have a file in this format:
0 2 4
3 2 4
3 5 2
1 8 2
My aim is to read the first line on each file and store it in a array. So at the end I should have 0,3,3,1
I thought one approach would be, read the line until we encounter a space and save that in a array...but it would keep on reading 2 and 4 after
Is there a efficient way of doing this, my cod is shown below:
openandprint()
{
int i = 0;
try (BufferedReader br = new BufferedReader(new FileReader("final.txt")))
{
String line;
while ((line = br.readLine()) != null) {
int change2Int=Integer.parseInt(line.trim());
figures [i] = change2Int;
i++;
}
}
catch (Exception expe)
{
expe.printStackTrace();
}
}
Using a Scanner would make the code considerably cleaner:
private static openandprint() throws IOException {
int i = 0;
try (Scanner s = new Scanner("final.txt"))) {
String line;
while (s.hasNextLine()) {
int change2Int = s.nextInt();
s.nextLine(); // ignore the rest of the line
figures [i] = change2Int;
i++;
}
}
}
Try
int change2Int=Integer.parseInt((line.trim()).charAt(0)-'0');
or
int change2Int=Character.getNumericValue(line.charAt(0));
with your approch you are reading the whole line and parsing it to int which will give you NumberFormatException because of the space between the digits.
BufferedReader br = ...;
String line = null;
while ((line = br.readLine()) != null) {
String[] parts = line.split(" ");
int next = Integer.parseInt(parts[0]);
System.out.println("next: " + next);
}

Find a specific line of a text file (not by line_number) and store it as a new String

I am trying to read a text file in java using FileReader and BufferedReader classes. Following an online tutorial I made two classes, one called ReadFile and one FileData.
Then I tried to extract a small part of the text file (i.e. between lines "ENTITIES" and "ENDSEC"). Finally l would like to tell the program to find a specific line between the above-mentioned and store it as an Xvalue, which I could use later.
I am really struggling to figure out how to do the last part...any help would be very much apprciated!
//FileData Class
package textfiles;
import java.io.IOException;
public class FileData {
public static void main (String[] args) throws IOException {
String file_name = "C:/Point.txt";
try {
ReadFile file = new ReadFile (file_name);
String[] aryLines = file.OpenFile();
int i;
for ( i=0; i < aryLines.length; i++ ) {
System.out.println( aryLines[ i ] ) ;
}
}
catch (IOException e) {
System.out.println(e.getMessage() );
}
}
}
// ReadFile Class
package textfiles;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.lang.String;
public class ReadFile {
private String path;
public ReadFile (String file_path) {
path = file_path;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader (path);
BufferedReader textReader = new BufferedReader (fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
String nextline = "";
int i;
// String Xvalue;
for (i=0; i < numberOfLines; i++) {
String oneline = textReader.readLine();
int j = 0;
if (oneline.equals("ENTITIES")) {
nextline = oneline;
System.out.println(oneline);
while (!nextline.equals("ENDSEC")) {
nextline = textReader.readLine();
textData[j] = nextline;
// xvalue = ..........
j = j + 1;
i = i+1;
}
}
//textData[i] = textReader.readLine();
}
textReader.close( );
return textData;
}
int readLines() throws IOException {
FileReader file_to_read = new FileReader (path);
BufferedReader bf = new BufferedReader (file_to_read);
String aLine;
int numberOfLines = 0;
while (( aLine = bf.readLine()) != null ) {
numberOfLines ++;
}
bf.close ();
return numberOfLines;
}
}
I don't know what line you are specifically looking for but here are a few methods you might want to use to do such operation:
private static String START_LINE = "ENTITIES";
private static String END_LINE = "ENDSEC";
public static List<String> getSpecificLines(Srting filename) throws IOException{
List<String> specificLines = new LinkedList<String>();
Scanner sc = null;
try {
boolean foundStartLine = false;
boolean foundEndLine = false;
sc = new Scanner(new BufferedReader(new FileReader(filename)));
while (!foundEndLine && sc.hasNext()) {
String line = sc.nextLine();
foundStartLine = foundStartLine || line.equals(START_LINE);
foundEndLine = foundEndLine || line.equals(END_LINE);
if(foundStartLine && !foundEndLine){
specificLines.add(line);
}
}
} finally {
if (sc != null) {
sc.close();
}
}
return specificLines;
}
public static String getSpecificLine(List<String> specificLines){
for(String line : specificLines){
if(isSpecific(line)){
return line;
}
}
return null;
}
public static boolean isSpecific(String line){
// What makes the String special??
}
When I get it right you want to store every line between ENTITIES and ENDSEC?
If yes you could simply define a StringBuffer and append everything which is in between these to keywords.
// This could you would put outside the while loop
StringBuffer xValues = new StringBuffer();
// This would be in the while loop and you append all the lines in the buffer
xValues.append(nextline);
If you want to store more specific data in between these to keywords then you probably need to work with Regular Expressions and get out the data you need and put it into a designed DataStructure (A class you've defined by our own).
And btw. I think you could read the file much easier with the following code:
BufferedReader reader = new BufferedReader(new
InputStreamReader(this.getClass().getResourceAsStream(filename)));
try {
while ((line = reader.readLine()) != null) {
if(line.equals("ENTITIES") {
...
}
} (IOException e) {
System.out.println("IO Exception. Couldn't Read the file!");
}
Then you don't have to read first how many lines the file has. You just start reading till the end :).
EDIT:
I still don't know if I understand that right. So if ENTITIES POINT 10 1333.888 20 333.5555 ENDSEC is one line then you could work with the split(" ") Method.
Let me explain with an example:
String line = "";
String[] parts = line.split(" ");
float xValue = parts[2]; // would store 10
float yValue = parts[3]; // would store 1333.888
float zValue = parts[4]; // would store 20
float ... = parts[5]; // would store 333.5555
EDIT2:
Or is every point (x, y, ..) on another line?!
So the file content is like that:
ENTITIES POINT
10
1333.888 // <-- you want this one as xValue
20
333.5555 // <-- and this one as yvalue?
ENDSEC
BufferedReader reader = new BufferedReader(new
InputStreamReader(this.getClass().getResourceAsStream(filename)));
try {
while ((line = reader.readLine()) != null) {
if(line.equals("ENTITIES") {
// read next line
line = reader.readLine();
if(line.equals("10") {
// read next line to get the value
line = reader.readLine(); // read next line to get the value
float xValue = Float.parseFloat(line);
}
line = reader.readLine();
if(line.equals("20") {
// read next line to get the value
line = reader.readLine();
float yValue = Float.parseFloaT(line);
}
}
} (IOException e) {
System.out.println("IO Exception. Couldn't Read the file!");
}
If you have several ENTITIES in the file you need to create a class which stores the xValue, yValue or you could use the Point class. Then you would create an ArrayList of these Points and just append them..

Categories