i have some marks for some students in my tutoring class...and also i'm trying to learn how to open and edit csv files as they're not like normal .txt files in Java so i thought this is the perfect opportunity.
i have a Students.csv file in this format:
132567 Amelia
123476 Charlie
123516 Emily
143456 George
123466 Harry
123457 Jack
125456 Joshua
132456 Lily
123456 Oliver
123459 Sophie
123486 Thomas
123518 William
The numbers are their student numbers followed by the students name.
and in a seperate .csv file i have their marks for modules alongside their student numbers in this format:
123456 51.2 57.3 68.2 72.1
123457 60.4 51.3 70 55
123459 45 60.1 62.7 43.2
123466 37.9 44 67.2 48.5
123476 52.7 78.2 73.3 69.8
123486 45.9 61.2 55.4 41.7
123516 61.2 66.4 72.3 57.8
123518 83.2 78.2 66.1 61.7
125456 69.8 60.3 72.1 64
132456 73.1 82.6 71.2 79.5
132567 56.3 48.8 45.7 61.2
143456 41.9 66.2 55.4 63.2
For each of the four modules, i want to create a new file that has all the students results in it. The names of these module report files can be anything for example IR101.txt, ..., IR104.txt. as i can change them later anyway.
i want the end result to be something like this:
Module: IR102
Mean: 62.88
00 - 39.9: 0
40 - 49.9: 2
50 - 59.9: 2
60 - 69.9: 5
70 - 100.0: 3
123466, Harry: 44.0
132567, Amelia: 48.8
123457, Jack: 51.3
123456, Oliver: 57.3
123459, Sophie: 60.1
125456, Joshua: 60.3
123486, Thomas: 61.2
143456, George: 66.2
123516, Emily: 66.4
123476, Charlie: 78.2
123518, William: 78.2
132456, Lily: 82.6
dont worry about doing the calculations for mean as i can implement that myself.
here is what i have so far, and all this does is open and print the students.csv file but i still cant figure out how to access each value and manipulate it as it's very different to python
public class excelfile {
public static final String students_file = "students.csv";
public static final String marks_file = "marks.csv";
public static String[] students() {
Scanner input = null;
try {
input = new Scanner(new File(students_file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String[] tmp = new String[14];
int c = 0;
while (input.hasNextLine()) {
tmp[c++] = input.nextLine();
}
input.close();
System.out.println(Arrays.deepToString(tmp));
return tmp;
}
public static void main(String[] args) {
students();
}
}
To point you the (basic/raw) way using regex to extract data :
String test = "123 John Maths 15.5";
Matcher matcher = Pattern.compile("(\\d+) (\\w+) (\\w+) (\\d+|\\d+\\.\\d+)").matcher(test);
if(matcher.matches()) {
System.out.println("ID = " + matcher.group(1));
System.out.println("Name = " + matcher.group(2));
System.out.println("Subject = " + matcher.group(3));
System.out.println("Mark = " + matcher.group(4));
}
The only condition for that to work is to have always the same format for CSV file.
The rest is up to you as it is easy to pars all files and just match each line from a file to a line from a second file.
Easiest way (without using classes, etc.) is to use simple Array or Map (Key will be the ID of student for example so yo ucan easily search for him).
Related
I have this text file containing various information so far I've been able to read everything except the Address details as they're separated by spaces and contain both numbers and letters so I'm a bit stuck as to what to do I've tried reading it as an int but I know that it wouldn't work.
This is my code:
public void methodName() {
File vData = new File("src/volunteer_data.txt"); // Create file object
try { // try catch to handle exception
Scanner readFile = new Scanner(vData); // Create scanner object
while (readFile.hasNextLine()) { //
int volunteerID = readFile.nextInt(); // Read volunteerID as an int
String vName = readFile.nextLine(); // Read volunteer name as string
// DATATYPE address = readFile.nextSOMETHING(); // Read address as ....
String contact = readFile.nextLine(); // Read contact number as a string
}
readFile.close(); // Close scanner
} catch(FileNotFoundException e) { // Throw exception and stop program if error found
e.printStackTrace();
}
Here is the text file that I am reading from. It is tab delimited:
VolunteerID Name Address Contact
050 John 24 Willow Street 905-747-0876
042 Emily 362 Sunset Avenue 905-323-1234
013 Alice 16 Wonderland Street 905-678-0987
071 Arthur 36 York Road 905-242-5643
060 Daniel 125 Ottawa Street 905-666-3290
055 Peppa 64 Great Britain Blvd 905-212-4365
024 Sean 909 Green Avenue 905-232-5445
077 Kim 678 Grape Garden 905-080-7641
098 Patrick 126 Oxford Street 905-099-9535
092 Laura 45 Mill Street 905-244-0086
008 Gary 84 California Street 905-767-3456
My advice is to forget scanning each column separately using nextInt() etc. It leads to pain and suffering in the long run. Instead, scan the whole line and work with the line: split it into a String[] of columns, then work with the columns separately:
readFile.nextLine(); // skip heading line (if there is one)
while (readFile.hasNextLine()) {
String line = readFile.nextLine(); // read whole line
String[] columns = line.split("\t"); // split line on tab char
// get each column into variables
int volunteerID = Integer.parseInt(columns[0]);
String vName = columns[1];
String address = columns[2]; // no big deal
String contact = columns[3];
// do something with variables
}
Strictly speaking, you don't even need the variables. Yo could work directly with the array and an index, but it's much easier to read and debug when you use well-named variables.
I need some help. I dont know how to solve my problem.
I have text file in this format:
personx 25
personz 2
persony 5
persony 7
personi 55
personx 25
I need to count the numbers for every person. The output should be "personx = 50" etc.
I can not use my old system where I knew there is 10 people. So I had 10 variables and I just went through the file with scanner and checked if line starts with "personx" then count the number to variable personx etc. I dont want to use these variables now. I dont want to change code after every new person.
How to solve this? I want to have this output sorted from highest to lowest:
personi = 55
personx = 50
persony = 12
personz = 2
Is that possible without using variables personi, personx, persony, personz ? My idea was to go through the file and scan the names. Save the name into an array and add another name into an array if that name is not in the array yet. So I will have the names.
Next I will scan the file again and check for the name and number. Check name + number and then save the number into another array on the same possition as the name in the first array. So I will have
Names[0] = "personi";
Count[0] = 55;
Names[1] = "personx";
Count[1] = 50;
And then I will just print these two arrays with for cycle.
I dont think that it is the best solution. How would you do it? Is there something better/faster/easier ? And how to solve that Sorting?
Thank you for your time.
You can us Map<String,Integer>
In this case i used TreeMap which will sort everything for you. If you dont need sorting then just use HashMap instead of TreeMap.
Map<String, Integer> map = new TreeMap();
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("C:/iPhone/persons.txt")));
String line = "";
String [] person = new String[2];
while ((line = reader.readLine()) != null) {
person = line.split(" ");
String name = person[0];
int number = Integer.parseInt(person[1]);
map.put(name,map.getOrDefault(name,0)+number);
}
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
map.forEach((k,v)->System.out.println(k + " = " + v));
}
persons.txt:
personx 25
personz 2
persony 5
persony 7
personi 55
personx 25
Output:
personi = 55
personx = 50
persony = 12
personz = 2
1) Can I use this on file where line is not in my format but it has for example.. this format ? "personx bla bla 25" ? Is it possible to convert it too? how?
Yes you can create method which will do it for you. You can use either string splits or some regex.
2) Why is there String [] person = new String[2]; ?
Mistake, it should be String[1]. Corrected now
3) what is String line = ""; ?
It is just new String where i'm storing every line that i read from file. As you can see, im assigning reder.readLine() in while loop. After that im just splitting it.
EDIT:
Changed code so person can have multiple params but will take only first as name and last as number.
public static void main(String[] args) {
Map<String, Integer> map = new TreeMap();
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("C:/iPhone/persons.txt")));
String line = "";
String [] person;
while ((line = reader.readLine()) != null) {
person = line.split(" ");
String name = person[0];
int number = Integer.parseInt(person[person.length-1]);
map.put(name,map.getOrDefault(name,0)+number);
}
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
map.forEach((k,v)->System.out.println(k + " = " + v));
}
persons.txt:
personx asdasdas dasd asd a 25
personz 2
persony asd asd asd a 5
persony 7
personi 55
personx 25
output:
personi = 55
personx = 50
persony = 12
personz = 2
I have this code so far, but I am having trouble with using the delimiter (I am new to regex as well as file reading).
File file = new File(ROOT_FOLDER + fname);
Scanner scanner = null;
try {
Pattern p = Pattern.compile("(?=\\D+)(?=[^\\.])");
scanner = new Scanner(file).useDelimiter(p);
while (scanner.hasNext()) {
String next = scanner.next();
UI.println(next);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Error(e);
} finally {
if (scanner != null)
scanner.close();
}
Sample of a file
Samples from database of fake names from http://www.fakenamegenerator.com/
All details are fictious!!
Mr. Jake M Goodwin 11 Yarmouth Road Mahora 4120 JakeGoodwin#teleworm.us (022) 6735-347 1998 Rolls-Royce Silver Spur 100.9 184
Mr. Samuel D Law 140 Small Street Dunedin Central 9016 SamuelLaw#cuvox.de (028) 0699-710 2001 Dodge Durango 113 180
What's getting to me is that if I use the default space delimiter, then numbers like (028) won't be detected as a number with hasNextDouble() (but using a regex I think means I can just use hasNext() instead anyway).
What is the proper delimiter I need to use? I am thinking of something like: Any number of non-digits and in a row, as long as it isn't a single dot.
You can use this :
try
{
//regex for matching only numbers and dot
Pattern p = Pattern.compile("[^0-9.]");
scanner = new Scanner(new FileReader(FILE_PATH)).useDelimiter(p);
while (scanner.hasNext()) {
String next = scanner.next();
if(!next.equals("") && !next.equals(".")) {
System.out.println(next);
}
}
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
finally
{
if (scanner != null)
scanner.close();
}
Input :
Samples from database of fake names from http://www.fakenamegenerator.com/
All details are fictious!!Mr. Jake M Goodwin 11 Yarmouth Road Mahora 4120 JakeGoodwin#teleworm.us (022) 6735-347 1998 Rolls-Royce Silver Spur 100.9 184
Mr. Samuel D Law 140 Small Street Dunedin Central 9016 SamuelLaw#cuvox.de (028) 0699-710 2001 Dodge Durango 113 180
Output :
11
4120
022
6735
347
1998
100.9
184
140
9016
028
0699
710
2001
113
180
I was given a file that has list of names phone numbers, calls in and out ect... Like this
Adams#Marilyn#8233331109#0#0#01012014#C
Anderson#John#5025559980#20#15#12152013#M
Baker-Brown#Angelica#9021329944#0#3#02112014#C
The # are delimiters between data items and each line has the call status as the last item.
I need to know how I can display each persons information on the screen in a format such as:
Name Phone Calls Out Calls In Last Call
Marilyn Adams (823) 333-1109 0 0 01-01-2104
John Anderson (502) 555-9980 20 15 12-15-2013
Angelica Baker-Brown (859) 254-1109 11 5 02-11-2014
I have to use substring method to extract the phone number and add parentheses/dashes ect...
So Far my code looks like this
Also I am in a beginners Java coding class....
import java.util.Scanner;
import java.io.*;
public class phonedata2_1 {
public static void main(String[] args) throws IOException {
String Phonefile, FirstName, LastName;
Scanner PhoneScan, fileScan;
System.out.println(" Name Phone Calls Out Calls In Last Call Status");
fileScan = new Scanner(new File("phonedata.txt"));
while (fileScan.hasNext()) {
Phonefile = fileScan.nextLine();
PhoneScan = new Scanner(Phonefile);
PhoneScan.useDelimiter("#");
System.out.println(PhoneScan.next() + " "
+ PhoneScan.next() + "\t"
+ PhoneScan.next() + "\t"
+ PhoneScan.next() + "\t"
+ PhoneScan.next() + "\t"
+ PhoneScan.next() + "\t"
+ PhoneScan.next());
}
System.out.println("\nTotal outgoing calls for the period: " + "\nTotal incoming calls for the period: \n");
}
}
Finds every "data-segment" by using regex, then splits it with # as delimiter and prints it:
File blub = new File("blub.txt");
Scanner scanner = null;
try
{
scanner = new Scanner(blub);
}
catch (FileNotFoundException e){}
while(scanner.hasNext("((\\S*)#){6}(\\w)"))
{
String buffer = scanner.next("((\\S*)#){6}(\\w)");
for(String value : buffer.split("#"))
System.out.print(value + " ");
System.out.println();
}
Output:
Adams Marilyn 8233331109 0 0 01012014 C
Anderson John 5025559980 20 15 12152013 M
Baker-Brown Angelica 9021329944 0 3 02112014 C
Note:
You can use any whitespace character to separate each data-segment in the input file, so even spaces are okay or tabs(or crazy mix with empty lines and so on).
For farther use of data:
you could add your data in an arraylist since buffer.split("#") gives you an array of the data-segment, so you can output it easier with your desired changes to each value.(or in a different order)
You can use the .split(String regex) to split the line you are reading by throwing in the # as a delimeter. This will yield an array which you can traverse and print the contents accordingly. Also, it would seem that besides the initial line, all call data starts with a , so you could use split twice to parse your text file:
EDIT: Seeing your comment, I also realized that afterwards, however, since the .split() method takes a regex as parameter, it means that this problem can be walked around without much hassle. My example is as follows:
String str = "Adams#Marilyn#8233331109#0#0#01012014#C Anderson#John#5025559980#20#15#12152013#M Baker-Brown#Angelica#9021329944#0#3#02112014#C";
String[] lines = str.split(" ");
System.out.println("Name\tPhone\tCalls\tOut\tCalls In\tLast Call");
for(String line : lines)
{
String[] lineInfo = line.split("#");
for(String info : lineInfo)
{
System.out.print(info + "\t");
}
System.out.println();
}
I had to add some extra tabs manually, but this is the output:
Name Phone Calls Out Calls In Last Call
Adams Marilyn 8233331109 0 0 01012014 C
Anderson John 5025559980 20 15 12152013 M
Baker-Brown Angelica 9021329944 0 3 02112014 C
Something like this should work. You still need to do all the manipulation of the phone number yourself, but all the data will be in the call info so you should be able to work from that!
while (fileScan.hasNext())
{
//Get a single record
Phonefile = fileScan.nextLine();
//Seperate the elements of the record
String[] callInfo = Phonefile.split("#");
for(String infoPart: callInfo)
{
System.out.print(infoPart+ "\t");
}
System.out.println()
}
I am writing a program that will read two files in from the command line and find how many words in each .txt file. I have got my code to work, however I need it to count each apostrophe as 2 words and each hyphen as two words. Something like this e.g., John's will become two separate words "john" and "s" and Tick-Tock will become "tick" and "tock"). I cannot use util.regex also. Here is my code"
private void readFile(){
Scanner scanner = null;
try {
scanner = new Scanner(file);
while (scanner.hasNextLine()){
String line = scanner.nextLine();
String[] wordOfLine = line.split("\\W");
lineNum++;//accumulate line
//counts all words
for (String word : wordOfLine){
if (word.equals("") || !(isWord(word)))
continue;
words.add(word.toLowerCase());
if (wordNum + 1 > wordNum){//in case of overflow
wordNum++;//accumulate word
}
else
throw new Error(" word number overflow!");
}
}
} catch (FileNotFoundException e) {
throw new Error("cannot find file!");
} finally{
if (scanner != null)
scanner.close();
}
System.out.println("Test for wordNum "+wordNum);
}
//check if text is word
private boolean isWord(String text) {
return text.matches("[a-zA-Z]+");
}
For example here is my test end results:
Test for wordNum 54
Test for wordNum 49516
File f1: 9 lines, 54 words, 38 distinct words
File f2: 4666 lines, 49516 words, 5103 distinct words
f1 matches fine with results expected
but f2 needs to be like this
File f2: 4666 lines, 49714 words, 5216 distinct words
here is some of the document for f2
THE PRINCE
by Nicolo Machiavelli
Translated by W. K. Marriott
Nicolo Machiavelli, born at Florence on 3rd May 1469. From 1494 to 1512
held an official post at Florence which included diplomatic missions to
various European courts. Imprisoned in Florence, 1512; later exiled and
returned to San Casciano. Died at Florence on 22nd June 1527.
INTRODUCTION
Nicolo Machiavelli was born at Florence on 3rd May 1469. He was the
second son of Bernardo di Nicolo Machiavelli, a lawyer of some repute,
and of Bartolommea di Stefano Nelli, his wife. Both parents were members
of the old Florentine nobility.
String[] tokens = "abc-def".split("((?<=-)|(?=-))");
System.out.println(Arrays.toString(tokens));
OUTPUT:
[abc, -, def]