I'm trying to analyze a list of albums from a file.There are 22 albums in my list and one of the items in the list is a duplicate and another is not in correct form.I'm supposed to throw two exceptions and print helpful messages on the console.My InputMismatchException is working fine, although my program should continue reading file inputs skipping the album object/line in the list where the exception occurred.Another exception is a DuplicateAlbumException, which is a custom exception.This exception should ignore the duplicate, print a helpful message on the console that mentions that the duplicate has been ignored , and only read the item one time. The following is my txt file that has inputs of albums:top20albums.txt
Led Zeppelin IV 1971
Led Zeppelin II 1969
Fleetwood Mac Rumors 1977
Pink Floyd The Wall 1979
XXXXX XXXXXXXXX XXXX
The Clash London Calling 1979
The Beatles Abbey Road 1969
Van Morrison Moondance 1971
Talking Heads Fear of Music 1979
Who Who's Next 1971
The Beatles Rubber Soul 1965
Cure Kiss Me, Kiss Me, Kiss Me 1987
Violent Femmes Violent Femmes 1982
Pink Floyd The Wall 1979
Soul Coughing Ruby Vroom 1994
James Laid 1993
Liz Phair Exile in Guyville 1993
Pink Floyd Dark Side of the Moon 1973
Police Zenyatta Mondatta 1980
Led Zeppelin Houses of the Holy 1973
Soul Coughing Irresistable Bliss 1996
Replacements Tim 1985
Expected output:
java AlbumList top20albums.txt
ERROR: Line 5: Invalid input for year. Skipping line
ERROR: Line 14: Duplicate album 'The Wall' by Pink Floyd
Album Rankings from top20albums.txt
Rank Title Artist Year
---- ------------------------------ -------------------- ----
1 IV Led Zeppelin 1971
2 II Led Zeppelin 1969
3 Rumors Fleetwood Mac 1977
4 The Wall Pink Floyd 1979
5 London Calling The Clash 1979
6 Abbey Road The Beatles 1969
7 Moondance Van Morrison 1971
8 Fear of Music Talking Heads 1979
9 Who's Next Who 1971
10 Rubber Soul The Beatles 1965
11 Kiss Me, Kiss Me, Kiss Me Cure 1987
12 Violent Femmes Violent Femmes 1982
13 Ruby Vroom Soul Coughing 1994
14 Laid James 1993
15 Exile in Guyville Liz Phair 1993
16 Dark Side of the Moon Pink Floyd 1973
17 Zenyatta Mondatta Police 1980
18 Houses of the Holy Led Zeppelin 1973
19 Irresistible Bliss Soul Coughing 1996
20 Tim Replacements 1985
My output on the eclipse console:
ERROR: Line 5: Invalid input for year. Skipping line.
Rank Title Artist Year
---- ----- ------ -----
1 IV Led Zeppelin 1971
2 II Led Zeppelin 1969
3 Rumors Fleetwood Mac 1977
4 The Wall Pink Floyd 1979
My effort so far is in the following:
class #1
// -------------------------------------------------------------------------
/**
* This Album class has four data fields; String title,String artist,
* int year, int rank.I will be creating an ArrayList of Album object in another class later
* which I will name as AlbumList.This Album class represents each Album o object in the
* top20albums.txt file, where we have 22 albums.
*
* #author Anonymous
* #version Mar 26, 2016
*/
public class Album
{
private String title;
private String artist;
private int year;
private int rank;
public Album () {
}
public Album(String title,String artist,int year,int rank) {
//this(title,artist,year);
this.title = title;
this.artist = artist;
this.year = year;
this.rank = rank;
}
public Album(String title,String artist,int year) {
this.title=title;
this.artist=artist;
this.year=year;
rank = -1;
}
public String getTitle()
{
return title;
}
public String getArtist()
{
return artist;
}
public int getYear()
{
return year;
}
public int getRank()
{
return rank;
}
public void setRank(int rank)
{
this.rank = rank;
}
/*
* // ----------------------------------------------------------
* overridden boolean method from the Object class which tests if
* two Album objects have the same artist and title or not.Later based on the
* invokation of the method we will throw the custom DuplicateAlbumException
*/
public boolean equals(Object obj) {
if(obj instanceof Album )
return (this.title.equals(((Album)obj).title)) && (this.artist.equals(((Album)obj).artist));
else
return this == obj;
}
public String toString() {
return String.format("%-4d %-30s %-20s %-4d", rank,title,artist,year);
}
}
class #2
import java.util.*;
import java.io.*;
// -------------------------------------------------------------------------
/**
* This AlbumList class will create ArrayList of Album objects, read inputs from the
* top20Albums.txt file and then analyze the album inputs.It will print album inputs
* on the console in neat columns, throw two exceptions; one is expected to occur at
* line 5 because of the type mismatch, another is expected to occur at line 15 because of
* the album duplication.I will later create a custom DuplicateAlbumException class that
* will throw exception when the Scanner reads the duplicate file and print a helpful
* message on the console.
*
* #author Anonymous
* #version Mar 26, 2016
*/
public class AlbumList
{
private List <Album> albums ;
public AlbumList(){
albums = new ArrayList<>();
}
// ----------------------------------------------------------
/**
* This method reads file input and throws exceptions robustly.
* #param inFile
*/
public void ReadAlbumsFromFile(File inFile) {
int count = 0;
int rank = 1;
try {
Scanner input = new Scanner(inFile);
input.useDelimiter("\\t|[\\n\\r\\f]+");
while (input.hasNext()) {
String artist = input.next();
String title = input.next();
int year = input.nextInt();
Album albumObject = new Album(title,artist,year,rank);
addAlbum(albumObject);
count ++;
rank++;
}
}
// This exception will not occur unless I give it a file input that does not exist.
catch (FileNotFoundException exception)
{
System.out.println("The file was not found.");
}
/* This exception works fine.However, the Scanner should continue reading the file
* inputs just skipping the 5th line where the mismatch occur.My program for some reason
* is not printing any more input after skipping the line and that is my problem.
*/
catch (InputMismatchException exception)
{
System.out.println("ERROR: Line "+(count+1)+": Invalid input for year. Skipping line.");
}
catch (DuplicateAlbumException exception)
{
System.out.println(exception.getMessage());
Album object = new Album();
System.out.println("ERROR: Line "+(count+1)+": Duplicate album"+object.getTitle()+" by "+object.getArtist());
}
}
// ----------------------------------------------------------
/**
* This DuplicateAlbumException should work fine if the Scanner keeps reading
* even after the mismatch exception occurs, at least that is what it seems
* to me because we are still unable to read line 15 where we expect the duplicate to occur.
* The custom duplicate exception class was already made.
* #param albumObject
* #throws DuplicateAlbumException
*/
public void addAlbum (Album albumObject) throws DuplicateAlbumException {
for(int i =0; i < albums.size();i++) {
if(albums.get(i).equals(albumObject)) {
throw new DuplicateAlbumException(albumObject.getTitle(),albumObject.getArtist());
}
}
/* Look that I am adding albumObjects after the catch blocks so IT SHOULD
* continue reading file inputs even after the exception occurs but it is not doing
* so.
*/
albums.add(albumObject);
}
public void printAlbums () {
albums.toString();
for (int i = 0; i < albums.size(); i++ )
System.out.println(albums.get(i));
}
public static void main(String [] args) throws Exception {
/*This is a way to write on the console so that the user can
* write the file name on the runtime console.
*/
if (args.length != 1) {
System.out.println("java AlbumList top20albums.txt ");
System.exit(0);
}
AlbumList albumListObject = new AlbumList();
File currentFile = new File(args[0]);
albumListObject.ReadAlbumsFromFile(currentFile) ;
System.out.println("\nRank Title \t\t\t Artist \t\t Year");
System.out.println("---- ----- \t\t\t ------ \t\t -----\n");
albumListObject.printAlbums();
}
}
class #3
// -------------------------------------------------------------------------
/**
* This is my custom exception class.
*
* #author Anonymous
* #version Mar 26, 2016
*/
public class DuplicateAlbumException extends ArrayStoreException
{
public DuplicateAlbumException(String title,
String artist) {
super ("Duplicate album" + title+
"by" + artist);
}
}
I hope my code blocks have enough information and explanation for you to understand my concern.But i would explicitly say it again: Why my Scanner stopped reading file input after the mismatch exception?
The problem is the .nextInt() is throwing the InputMismatchException causing the control to go out of the while loop. Refactor the code to
try {
Scanner input = new Scanner(inFile);
input.useDelimiter("\\t|[\\n\\r\\f]+");
while (input.hasNext()) {
try{
String artist = input.next();
String title = input.next();
int year = input.nextInt();
Album albumObject = new Album(title,artist,year,rank);
addAlbum(albumObject);
count ++;
rank++;
}
catch (InputMismatchException exception)
{
System.out.println("ERROR: Line "+(count+1)+": Invalid input for year. Skipping line.");
}
}
}
// This exception will not occur unless I give it a file input that does not exist.
catch (FileNotFoundException exception)
{
System.out.println("The file was not found.");
}
/* This exception works fine.However, the Scanner should continue reading the file
* inputs just skipping the 5th line where the mismatch occur.My program for some reason
* is not printing any more input after skipping the line and that is my problem.
*/
I hope this solves your problem
First of we are going to use a set, because you do not want duplicate albums.
Second we are going to say each line has an album. The reason to do this is because your Scanner will not advance when there is an input missmatch exception. Then you have another problem, where you scanner is not on the next line.
Set<Album> albums = new HashSet<>();
try(
BufferedReader reader = Files.newBufferedReader(
inFile.toPath(), Charset.forName("UTF8")
)
){
String line;
while((line = reader.readline())!=null){
Scanner input = new Scanner(line);
input.useDelimiter("\\t|[\\n\\r\\f]+");
int rank = 0;
try{
String artist = input.next();
String title = input.next();
int year = input.nextInt();
Album albumObject = new Album(title,artist,year,rank);
if(albums.add(albumObject){
rank++;
} else{
throw new DuplicateAlbumException("album: " + title + " exists");
}
} catch(InputMissmatchException exc){
//print out an error about a bad line.
} catch(DuplicateAlbumException exc){
//print out an error about a duplicate album.
}
}
} catch(IOException e){
//problem with the file
}
One more thing, your Album class needs to override hashcode.
#Override
public int hashCode(){
return title.hashCode() + artist.hashCode();
}
Related
I have been making this program for school and am getting stuck on a single exception from my scanner in the main function. It works with the states.txt file, but as soon as I ask for the input of the state abbreviation it throws me "Exception in thread "main" java.util.NoSuchElementException: No line found". Ive played around with it and cannot seem to get it to work. The error is on line 103.
Ive attempted to add the input string above the print statement and add the input string within the print statement with no luck. Ive rewrote it and tried to change the type of input.
Prog1.java
import java.util.*;
import java.io.*;
//State class
class State {
//instance variables
String name;
String abbreviation;
long population;
//non-parameterised constructor
State() {
}
//parameterised constructor
State(String name, String abbreviation, long population) {
this.name = name;
this.abbreviation = abbreviation;
this.population = population;
}
}
//Driver class: Prog1
public class Prog1 {
//ArrayList to store the states
ArrayList<State> states;
//constructor
Prog1() {
//initializing the list
states = new ArrayList<>();
}
//method to read the file (states.txt)
public void readFile(String fileName) {
//File object created
File file = new File(fileName);
//Scanner object helps to read the file
Scanner fileScanner;
//try-catch block to handle exceptions that might occur
try {
//initializing the fileScanner
fileScanner = new Scanner(file);
//reading the text file
while (fileScanner.hasNext()) {
//read each line and split wherever ", " occurs
String splits[] = fileScanner.nextLine().split(" ");
//storing the variables
String name = splits[0];
String abbreviation = splits[1];
long population = Long.parseLong(splits[2].trim());
//creating a state object
State state = new State(name, abbreviation, population);
//adding the state object to the list
states.add(state);
}
//closing the scanner resource
fileScanner.close();
} catch (Exception e) {
//catch block to handle exceptions (if any)
System.out.println("ERROR!!");
e.printStackTrace();
}
}
//method to print the data in table format
public void printStates() {
System.out.printf("%15s %2s %10s", " STATE ", "ABBREVIATION ", "POPULATION\n");
System.out.println("----------------------------------------------------");
for (State state : states) {
System.out.printf("%15s %8s %12s", state.name, state.abbreviation, Long.toString(state.population));
System.out.println();
}
}
//method to search state data for the entered Abbreviation
public void searchState(String key) {
for (State state : states) {
if (state.abbreviation.trim().equals(key)) {
System.out.println("STATE FOUND");
System.out.println("State: " + state.name + " \t Population: " + state.population);
return;
}
}
System.out.println("STATE NOT FOUND! TRY AGAIN!");
}
//main method
public static void main(String[] args) {
//creating Prog1 object
Prog1 p = new Prog1();
//method calls
p.readFile("states.txt");
p.printStates();
//Scanner object helps to read user input
Scanner scanner = new Scanner(System.in);
System.out.println("Please Enter abbreviation of the state to be searched: ");
String input = scanner.nextLine();
//The error happens right here
//method call
p.searchState(input);
}
}
states.txt
AL Alabama 4858979
AK Alaska 738432
AZ Arizona 6828065
AR Arkansas 2978204
CA California 39144818
CO Colorado 5456574
CT Connecticut 3590886
DE Delaware 945934
FL Florida 20271272
GA Georgia 10214860
HI Hawaii 1431603
ID Idaho 1654930
IL Illinois 12859995
IN Indiana 6619680
IA Iowa 3123899
KS Kansas 2911641
KY Kentucky 4425092
LA Louisiana 4670724
ME Maine 1329328
MD Maryland 6006401
MA Massachusetts 6794422
MI Michigan 9922576
MN Minnesota 5489594
MS Mississippi 2992333
MO Missouri 6083672
MT Montana 1032949
NE Nebraska 1896190
NV Nevada 2890845
NH NewHampshire 1330608
NJ NewJersey 8958013
NM NewMexico 2085109
NY NewYork 19795791
NC NorthCarolina 10042802
ND NorthDakota 756927
OH Ohio 11613423
OK Oklahoma 3911338
OR Oregon 4028977
PA Pennsylvania 12802503
RI RhodeIsland 1056298
SC SouthCarolina 4896146
SD SouthDakota 858469
TN Tennessee 6600299
TX Texas 27469114
UT Utah 2995919
VT Vermont 626042
VA Virginia 8382993
WA Washington 7170351
WV WestVirginia 1844128
WI Wisconsin 5771337
WY Wyoming 586107
I have a txt document where each line is an independent message. This may include name, date of birth, address, etc. In addition to the address, all other information is in a row. Their order is not fixed. Name and birthday must be available, other information may not be available. If there is no name or birthday, this person should be ignored. Different people use blank lines to distinguish them. I want to read this information and put them in the arraylist, but I have no idea how to write the code.
My initial idea was to use a loop to read the content and store it, and if there was a blank line, start saving another content. But how to implement the code specifically I have no idea.
public class InforProcessor {
private File recordFile;
private File instructionFile;
private File outputFile;
private InforList inforlist;
public InforProcessor(String[]s)
{
recordFile = new File(s[0]);
instructionFile = new File(s[1]);
outputFile = new File(s[2]);
inforlist = new InforList();
}
}
This is my existing code, I want to read the contents of the recordFile and write to the arraylist.
Input file is likeļ¼
name john
birthday 11-11-2015
Address 11 Harry St, montain, TRY
birthday 12-25-2017
name peter
Postcode 2005
name jane
birthday 25-19-1998
Address 25 jeoje St, Sky, FLY
Postcode 1998
name geoge
The output information or useful information should be:
name john
birthday 11-11-2015
Address 11 Harry St, montain, TRY
birthday 12-25-2017
name peter
Postcode 2005
name jane
birthday 25-19-1998
Address 25 jeoje St, Sky, FLY
The last information should be delete because it do not have birthday.
First,you need to read all line from file,and every message splited by empty line.
Second,iterate over the message and check the messag is valid or not,if the message is valid then add the message to list.
private static List<String> filterFile(final String input) throws Exception {
List<String> result = new ArrayList<>();
List<String> lines = FileUtils.readLines(new File(input), "UTF-8");
System.out.println(lines.size());
int begin = 0;
int end = 0;
for (; end < lines.size(); end++) {
if (Strings.isNullOrEmpty(lines.get(end))) {
if (isValidInfo(lines, begin, end)) {
result.addAll(lines.subList(begin, end + 1));
}
begin = end + 1;
}
}
return result;
}
if message has name and birthday,the message is we want.
private static boolean isValidInfo(List<String> infos, int begin, int end) {
int counts = 0;
for (int i = begin; i < end; i++) {
String line = infos.get(i);
if (line.startsWith("name")) {
counts++;
}
if (line.startsWith("birthday")) {
counts++;
}
}
return counts == 2;
}
I am struggling to read this stack trace exception below. I wonder If you could help me?
I don't understand any of the numbers in the code (like the number 74, 2119 and 2160, what do they represent in this exception? Quite literally, I need to know which line of my code is causing problems so that I can resolve it. Please help.
Here below is my stack trace, and beneath it is the java code I am trying to resolve alongside a sample input file which came with the task.
java.util.InputMismatchException
in java.util.Scanner.throwFor(Scanner.java:909)
in java.util.Scanner.next(Scanner.java:1530)
in java.util.Scanner.nextInt(Scanner.java:2160)
in java.util.Scanner.nextInt(Scanner.java:2119)
in League.loadLeague(League.java:74)
in (Workspace:1)
And here, below is my Java code with the method loadLeague which is causing me a lot of headache!
import java.io.*;
import java.util.*;
/**
* Class League - An instance of this class represents the teams in a
* football (or similar) league. It provides a class method for creating
* a new instance of League by reading the data for the teams from a CSV
* file.
*
* #author Lewis Jones
* #version 1.0
*/
public class League
{
/* instance variables */
private String name; // The name of the league
private Team[] teams; // An array to hold the teams in the league
/**
* Constructor for objects of class League. It sets the name of the league
* to the String object provided as the first argument and initialises teams
* to an array of the size provided as the second argument. This constructor
* is private as it is intended for use only by the class method loadLeague().
*/
private League(String aName, int size)
{
super();
this.name = aName;
this.teams = new Team[size];
}
/* class method */
/**
* This method creates a new League object by reading the required details from
* a CSV file. The file must be organised as follows:
* name(String), number of teams (int)
* team name(String), won(int), drawn(int), lost(int), for(int), against (int)
* and so on for each team
* Having created the new League object the method should create all the Team
* objects (using the data in the file to set their attributes) and add them
* to the teams array.
*/
public static League loadLeague()
{
League theLeague = null;
String pathname = OUFileChooser.getFilename();
File aFile = new File(pathname);
Scanner bufferedScanner = null;
try
{
String leagueName;
int numberOfTeams;
String teamName;
int won;
int drawn;
int lost;
int goalsFor;
int goalsAgainst;
Scanner lineScanner;
String currentLine;
bufferedScanner = new Scanner(new BufferedReader(new FileReader (aFile)));
while (bufferedScanner.hasNextLine())
{
currentLine = bufferedScanner.nextLine();
lineScanner = new Scanner(currentLine);
lineScanner.useDelimiter(",");
leagueName = bufferedScanner.next();
numberOfTeams = bufferedScanner.nextInt();
teamName = bufferedScanner.next();
won = lineScanner.nextInt();
drawn = lineScanner.nextInt();
lost = lineScanner.nextInt();
goalsFor = lineScanner.nextInt();
goalsAgainst = lineScanner.nextInt();
Team aTeam = new Team(lineScanner.next());
aTeam.setWon(lineScanner.nextInt());
aTeam.setDrawn(lineScanner.nextInt());
aTeam.setLost(lineScanner.nextInt());
aTeam.setGoalsFor(lineScanner.nextInt());
aTeam.setGoalsAgainst(lineScanner.nextInt());
Team[] teams = new Team[numberOfTeams];
teams[numberOfTeams] = aTeam;
numberOfTeams++;
theLeague = new League(leagueName, numberOfTeams);
}
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
finally
{
try
{
bufferedScanner.close();
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
}
return theLeague;
}
/* instance methods */
/**
* Displays the league table in tabular format to the standard output
*/
public void display()
{
System.out.println(this.name);
System.out.format("%20s %2s %2s %2s %2s %2s %2s % 2s\n","","P","W","L","D","F","A","Pt");
for (Team eachTeam : this.teams)
{
System.out.format("%20s %2d %2d %2d %2d %2d %2d %2d\n",
eachTeam.getName(), eachTeam.getPlayed(),
eachTeam.getWon(), eachTeam.getDrawn(),
eachTeam.getLost(),eachTeam.getGoalsFor(),
eachTeam.getGoalsAgainst(), eachTeam.getPoints());
}
}
/**
* Arrange the elements of teams in their natural order. This will only
* work if a natural order has been defined for the class Team.
*/
public void sort()
{
// to be written later...
}
}
And below is the sample (file) input which the program is supposed to read into:
Scottish League Division 1,10
Airdrie United ,3,2,11,14,25
Clyde ,5,7,4,21,17
Dundee ,7,2,7,21,18
Gretna ,10,3,3,43,20
Hamilton Acas ,7,5,4,19,20
Livingstone ,6,6,4,21,15
Partick Thistle,8,4,4,25,29
Queen of South ,3,3,10,11,31
Ross County ,4,4,8,14,24
St Johnstone ,6,6,4,26,16
I have really struggled with this task for nearly a week now! I hope someone out there comes to my rescue as it's really getting on my skin now. Please help. Any tips to pinpoint which code I'm writing wrongly would be so much appreciated.
Thank you guys,
Lew.
Those numbers (74, 2119 and 2160) are the code lines. The top most line of the stack trace is where the actual error occurred, and the rest are the call locations in the stack trace.
So in this event, Scanner.java:909 means that the error occurred at line 909 of the Scanner class, which was in a function called at line 1530 in Scanner, and so on and so forth.
This code takes in users and movies from two separate files and computes a user score for a movie. When I run the code I get the following error:
Exception in thread "main" java.lang.NullPointerException
at RecommenderSystem.makeRecommendation(RecommenderSystem.java:75)
at RecommenderSystem.main(RecommenderSystem.java:24)
I believe the NullPointerException is due to an error in this particular class but I can't spot it. Any thoughts?
import java.io.*;
import java.lang.Math;
public class RecommenderSystem
{
private Movie[] m_movies;
private User[] m_users;
/** Parse the movies and users files, and then run queries against them.
*/
public static void main(String[] argv)
throws FileNotFoundException, ParseError, RecommendationError
{
FileReader movies_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10.txt");
FileReader users_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10-users.txt");
MovieParser mp = new MovieParser(movies_fr);
UserParser up = new UserParser(users_fr);
Movie[] movies = mp.getMovies();
User[] users = up.getUsers();
RecommenderSystem rs = new RecommenderSystem(movies, users);
System.out.println("Alice would rate \"The Shawshank Redemption\" with at least a "
+ rs.makeRecommendation("The Shawshank Redemption", "asmith"));
System.out.println("Carol would rate \"The Dark Knight\" with at least a "
+ rs.makeRecommendation("The Dark Knight", "cd0"));
}
/** Instantiate a recommender system.
*
* #param movies An array of Movie that will be copied into m_movies.
* #param users An array of User that will be copied into m_users.
*/
public RecommenderSystem(Movie[] movies, User[] users)
throws RecommendationError
{
m_movies = movies;
m_users = users;
}
/** Suggest what the user with "username" would rate "movieTitle".
*
* #param movieTitle The movie for which a recommendation is made.
* #param username The user for whom the recommendation is made.
*/
public double makeRecommendation(String movieTitle, String username)
throws RecommendationError
{
int userNumber;
int movieNumber;
int j=0;
double weightAvNum =0;
double weightAvDen=0;
for (userNumber = 0; userNumber < m_users.length; ++userNumber)
{
if (m_users[userNumber].getUsername().equals(username))
{
break;
}
}
for (movieNumber = 0; movieNumber < m_movies.length; ++movieNumber)
{
if (m_movies[movieNumber].getTitle().equals(movieTitle))
{
break;
}
}
// Use the weighted average algorithm here (don't forget to check for
// errors).
while(j<m_users.length){
if(j!=userNumber){
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
weightAvDen = weightAvDen + (m_users[userNumber].similarityTo(m_users[j]));
}
j++;
}
return (m_users[userNumber].getAverageRating()+ (weightAvNum/weightAvDen));
}
}
class RecommendationError extends Exception
{
/** An error for when something goes wrong in the recommendation process.
*
* #param s A string describing the error.
*/
public RecommendationError(String s)
{
super(s);
}
}
If the file you posted is unaltered from the file that generated the stack trace you posted, then the nullpointer exception on line 75 is somewhere in this code:
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
So since m_users is not null (otherwise it would have crashed earlier) either m_users[j] or m_users[userNumber] is null, i.e., there is some null element in the m_users array.
I have a text file input which contains data as below. How can I display data from the text file into specific format?
Monday
Jessy
Walking
20 minutes
Matthew
Run
20 minutes
Karen
Jogging
40 minutes
Jessica
Run
12 minutes
Tuesday
Messia
Walking
10 minutes
Matthew
Run
20 minutes
Pete
Run
10 minutes
Carol
Walking
30 minutes
I want to display data from the text file into this format:
Day Name Type of exercise Time
Monday Jessy Walking 20 minutes
Matthew Run 20 minutes
Karen Jogging 40 minutes
Jessica Run 12 minutes
Tuesday Messia Walking 10 minutes
Matthew Run 20 minutes
Pete Run 10 minutes
Carol Walking 30 minutes
I just threw this together quickly, but what about something like:
static final String[] DAYS =
{ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
public class ActivityEvent
{
public int day;
public String name;
public String typeOfExercise;
public String time;
}
public List loadActivities(String filename) throws IOException
{
List activities = new ArrayList();
FileInputStream fis = new FileInputStream(filename);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
int lastDay = -1;
String line;
while ((line = br.readLine()) != null)
{
line = line.trim();
int day;
for (day = DAYS.length - 1; day >= 0; day--)
{
if (line.equals(DAYS[day]))
{
break;
}
}
String name;
if (day < 0)
{
day = lastDay;
if (lastDay < 0)
{
throw new IOException(filename + " must start with day of week");
}
name = line;
}
else
{
name = br.readLine();
if (name == null)
{
throw new IOException(filename + " expected name, reached end of file");
}
}
String type = br.readLine();
if (type == null)
{
throw new IOException(filename + " expected type of exercise, reached end of file");
}
String time = br.readLine();
if (time != null)
{
throw new IOException(filename + " expected time of exercise, reached end of file");
}
ActivityEvent activity = new ActivityEvent();
activity.day = day;
activity.name = name;
activity.typeOfExercise = type;
activity.time = time;
activities.add(activity);
}
return activities;
}
public void printActivities(List activities)
{
StringBuilder str = new StringBuilder("Day\tName\tType of Exercise\tTime\n");
int numActivities = activities.size();
int lastDay = -1;
for (int index = 0; index < numActivities; index++)
{
ActivityEvent activity = (ActivityEvent)activities.get(index);
if (activity.day != lastDay)
{
str.append(DAYS[activity.day]);
}
str.append('\t');
str.append(activity.name);
str.append('\t');
str.append(activity.typeOfExercise);
str.append('\t');
str.append(activity.time);
str.append('\n');
}
System.out.print(str.toString());
}
And then invoke everything for example:
List activities = loadActivities("somefile.txt");
// Do optional sorting, etc. here.
printActivities(activities);
I would have a look at Java's sprintf() function and it's ability to left/right justify data with specified widths.
Regarding parsing the input:
One issue you will have is that each "record" of data (each row, in the ouput) is not a fixed size.
Some are 3-tuples of name,exercise,time, and others are 4-tuples of day,name,exercise,time
That said, assuming the format you've given is really all there is to it, the issue can be worked around.
After reading a line, you could check for a weekday, and if so assume that's the start of a 4-tuple, and read the next 3 lines.
If it is not a weekday, then assume it is a 3-tuple, and only read the next 2 lines.
If there might be "gaps" in the name, type, or time columns in the output as well, and in different combinations, it gets trickier.
You really need your program to have special knowledge about what values are valid in what columns. Eg, that 'Jessica' is not a valid type of exercise, and 'Jogging' is not a valid name.
Regarding formatting the output
Brian's answer is relevant.
It depends on the language you use. Most languages have a printf-equivalent.
The formatting codes of printf allow you to pad with space, etc.
If you are using Perl (might be well-suited to this task), you can use formats