Loading information from file in different ways - java

My program currently has this working:
Bank bank = new Bank();
bank.openAccount(new CheckingAccount(10100, new Customer("First", "Last"),500.00,false));
bank.openAccount(new CheckingAccount(10101, new Customer("First", "Last"),2000.00,true));
bank.openAccount(new SavingsAccount(2010, new Customer("First", "Last"),5000.00,0.02));
Now I am trying to load this information from a file instead, but I ran into a bit of a wall. I want the new Customer information to include both the first and last name which are stored in separate index positions as separate variables, but while this will work:
new Customer[FIRST_INDEX],
I can't seem to get it to accept two index positions without creating a new Customer again. This is turn is causing issue with the method in Accounts where I'd like to keep the same format. How can I go about doing this?
public CheckingAccount(int accountNumber, Customer owner, double currentBalance, boolean freeChecks)
{
super(accountNumber, owner, currentBalance);
this.freeChecks = freeChecks;
}
Another problem I am running into is that the last index position can be one of two variables depending on if I am dealing with a checking account or a savings account:
private final static int FREE_CHECKS_INDEX = 4; // This loads a boolean
private final static int INTEREST_INDEX = 4; // This loads a double
Given this, I'm not entirely sure if my above approach would even work at all. The program is supposed to load either a Checking Account or Savings Account object, but since both types of accounts are stored in the same file I am wondering if I could read the last index position of each line of the text file before creating the object, but I'm not really sure how to go about doing that.
To be clear, I have this problem working perfectly without loading the data from the file, I am just unsure about the best approach for adapting it without having to rewrite all my other classes. Here's the new thing I am trying to do which I know isn't right:
protected static void loadAccountInformationFromFile() throws Exception
{
try ( Scanner fin = new Scanner(new File(INPUT_CUSTOMER_FILE)) )
{
String record;
String[] fields;
while ( fin.hasNext() )
{
record = fin.nextLine();
fields = record.split(",");
Bank bank = new Bank();
bank.openAccount
(
new CheckingAccount(Integer.parseInt(accountNumber[ACCOUNT_NUMBER_INDEX]),
new Customer[FIRST_INDEX, LAST_INDEX],
currentBalance[BALANCE_INDEX],
freeChecks[FREE_CHECKS_INDEX]
)
);
}
} catch (Exception e)
{
throw e;
} // end try
}

Related

How do I read files as a object or is there a better solution to this? Please see code bellow for context

So in my java class, we need to read this file and somehow converts its content into an object
import java.util.Scanner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Calendar {
public Appointment[] appointments;
Calendar()
{
appointments = null;
}
Calendar(int capacity, String filename)
{
Appointment[] appointments = new Appointment[capacity];
//you can see that appointments is an Appointment object
readCalendarFromFile(filename);}
private void readCalendarFromFile(String fileName){
Scanner fileRead = null;
try
{
fileRead = new Scanner(new FileInputStream("appointments.txt"));
for(int r = 0; r < 30; r++)
appointments[r]= fileRead.nextLine(); ----> This is where I am getting my error from as I cannot convert String into an object. Is there a way that I can pass this
fileRead.close();
}
catch (FileNotFoundException fe)
{
fe.printStackTrace();
System.err.println("Unable to open the file " + fileName + " for reading.");
}
}
}
Is there any way that I can convert filetext into an object or do I have to do something else with it? I have to make an appointment an object so I can't change it into anything else sadly.
You have to have a class Appointment somewhere, and what you are trying to do is add an object of the type Appointment to the array appointments, based on the info you get from the text file, right?
So, you have your for loop that reads every line from the text file, and then you need to create instances of Appointment for each line.
The class Appointment has some kind of constructor, that you need to call to create a new object (read: "a new instance") from it.
Let's assume it looks like this:
public Appointment(String title, String time, String location) {
this.title = title;
this.time = time;
this.location = location;
}
Let's also assume that every line in the file appointments.txt is formatted in the following way:
<Title>, <Time>, <Location>
Which means, that you would have to parse the line that you read from the file by splitting it (the delimiter in this case would be the ",". Just do a quick research on the internet on how to split Strings in Java, it's pretty easy actually.
When you have all the bits of information in separate variables, you have to call the constructor of Appointment, to create a new appointment that you can then add to your array. Assuming that you have three Strings with the title, the time and the location of the appointment (or whatever info you have in the text file), this would look like this:
try{
fileRead = new Scanner(new FileInputStream("appointments.txt"));
int counter = 0;
while(fileRead.hasNext()) {
String lineRead = fileRead.nextLine();
// here comes the parsing of the line into three String variables
appointments[counter] = new Appointment(title, time, location);
fileRead.close();
}
} catch(FileNotFoundException ex) {
// Do some exception handling in here, or just print the stacktrace
}
The line I want you to pay the most attention to is the Line, where it says new Appointment(title, time, location). The difference between this and the code that you posted is, that here I create a new object of the type Appointment, that corresponds with the type of the array you created earlier, in the line Appointment[] appointments = new Appointment[capacity].
You tried to directly add a String to the array, although you declared an array of the type Appointment, not of the type String.
You should read up on the topic of objects in Java in general, and what constructors are, what they do and how you use them.
For example, this topic gets explained really well and exhaustive in the official Java tutorials from Oracle (the company that develops the Java Language). I linked you the specific section that talks about constructors, but I would suggest that you read at least the whole chapter and everything before it that helps you understand what they actually talk about.
Hope this helps :)

Updating Arraylist by reading from dat file

so part of my program does is to create a card with a name. ill then check if the name exists in my dat file.
first, what i do is i read in my dat file and stores into an arraylist. then i implement a method to check if name exists. if not, then go ahead with creation.
but the thing is, after creation, i need to update my existing arraylist as my dat file has been updated with the newly added name.
what im thinking now is to clear my existing arraylist and then reading+store it again.
but i keep running into exceptions when i introduce the clear method. Here are my tested codes:
private ArrayList<Cards> cardList;
public void readGameCards()
{
cardList = new ArrayList<Cards>();
//clearCards(this.cardList); -> not sure where to add this
try // get data from dat file and store it into arraylist
{
Scanner myScanner = new Scanner(new File("GameCards.dat"));
while (myScanner.hasNextLine())
{
//converting codes
Cards c = new Cards(//para);
cardList.add(c);
}
myScanner.close();
}
catch (FileNotFoundException fe)
{
System.out.println("...");
}
}
public void clearCards(ArrayList<Cards> cardList)
{
if (!cardList.isEmpty())
{
cardList.clear();
//cardList = new ArrayList<Cards>();
}
}
it works fine for the first run, but on second run, the newly added name is not reflected in the arraylist.

Don't know how to add string to arraylist and make it stick

I'm new to java and I was trying to test what I've learned by creating a TestAddRemove program. Essentially it's supposed to make you choose one of two arrays and allows you to add a company name, remove a company name and read whether a company you're looking for is in one of the arrays.
My main problem is with the adding to the arrays part. Each time I add a company using the Add class it works, but then when I check the arrays again the arrays are empty.
Main Question: How do I add a companyName to an array in the main program and have it stick?
Here's my code:
public class TestAddRemove
{
static Scanner sc = new Scanner(System.in);
static ArrayList<String> fileOne = new ArrayList<String>();
static ArrayList<String> fileTwo = new ArrayList<String>();
:
: //Some other stuff
:
String tryAgain = "Y";
String answer;
String fileAnswer;
System.out.println("Welcome to the company tester; this program tests whether the company"
+ "you input is a company we already received donations from or a company we have"
+ "spoken to already, but declined to donate.");
while (tryAgain.equalsIgnoreCase("Y"))
{
System.out.println("Do you want to test, add or remove a company name? ");
answer = sc.next();
String companyName;
if (answer.equalsIgnoreCase("add"))
{
System.out.println("Which file do you want to add to?");
fileAnswer = sc.next();
if (fileAnswer.equalsIgnoreCase("fileOne"))
{
Add file = new Add(fileOne);
System.out.println("Enter the company name you want to add. ");
companyName = sc.next();
file.addCompany(companyName);
}
else
{
Add file = new Add(fileTwo);
System.out.println("Enter the company name you want to add. ");
companyName = sc.next();
file.addCompany(companyName);
}
The rest of the code is for the remove and test methods which I think I could understand once I understand how to add the companyName.
Here's the Add Class:
public class Add
{
Scanner sc = new Scanner(System.in);
ArrayList<String> file;
public Add(ArrayList<String> fileOne)
{
this.file = fileOne;
}
public void addCompany (String companyName)
{
file.add(companyName);
}
public ArrayList<String> getFile()
{
return file;
}
}
Any help on this would be awesome, thanks and cheers!
Running a Java application spawns a new JVM container. Such a container has its own memory in which it stores state for your program. When an application terminates, the JVM shuts down and discards all existing state. When you run the program a second time it runs in a different JVM totally unaware of any previous runs.
Regarding your problem, to access the list of companies created in a previous run, you need to add some sort of a persistence layer to your application like a database or a file in which you're able to store the companies.
The simplest solution would be to store the list in a text file, where each line represents one company, before the application shuts down and then load the file again when the application starts.

text classifier with weka: how to correctly train a classifier issue

I'm trying to build a text classifier using Weka, but the probabilities with distributionForInstance of the classes are 1.0 in one and 0.0 in all other cases, so classifyInstance always returns the same class as prediction. Something in the training doesn't work correctly.
ARFF training
#relation test1
#attribute tweetmsg String
#attribute classValues {politica,sport,musicatvcinema,infogeneriche,fattidelgiorno,statopersonale,checkin,conversazione}
#DATA
"Renzi Berlusconi Salvini Bersani",politica
"Allegri insulta la terna arbitrale",sport
"Bravo Garcia",sport
Training methods
public void trainClassifier(final String INPUT_FILENAME) throws Exception
{
getTrainingDataset(INPUT_FILENAME);
//trainingInstances consists of feature vector of every input
for(Instance currentInstance : inputDataset)
{
Instance currentFeatureVector = extractFeature(currentInstance);
currentFeatureVector.setDataset(trainingInstances);
trainingInstances.add(currentFeatureVector);
}
classifier = new NaiveBayes();
try {
//classifier training code
classifier.buildClassifier(trainingInstances);
//storing the trained classifier to a file for future use
weka.core.SerializationHelper.write("NaiveBayes.model",classifier);
} catch (Exception ex) {
System.out.println("Exception in training the classifier."+ex);
}
}
private Instance extractFeature(Instance inputInstance) throws Exception
{
String tweet = inputInstance.stringValue(0);
StringTokenizer defaultTokenizer = new StringTokenizer(tweet);
List<String> tokens=new ArrayList<String>();
while (defaultTokenizer.hasMoreTokens())
{
String t= defaultTokenizer.nextToken();
tokens.add(t);
}
Iterator<String> a = tokens.iterator();
while(a.hasNext())
{
String token=(String) a.next();
String word = token.replaceAll("#","");
if(featureWords.contains(word))
{
double cont=featureMap.get(featureWords.indexOf(word))+1;
featureMap.put(featureWords.indexOf(word),cont);
}
else{
featureWords.add(word);
featureMap.put(featureWords.indexOf(word), 1.0);
}
}
attributeList.clear();
for(String featureWord : featureWords)
{
attributeList.add(new Attribute(featureWord));
}
attributeList.add(new Attribute("Class", classValues));
int indices[] = new int[featureMap.size()+1];
double values[] = new double[featureMap.size()+1];
int i=0;
for(Map.Entry<Integer,Double> entry : featureMap.entrySet())
{
indices[i] = entry.getKey();
values[i] = entry.getValue();
i++;
}
indices[i] = featureWords.size();
values[i] = (double)classValues.indexOf(inputInstance.stringValue(1));
trainingInstances = createInstances("TRAINING_INSTANCES");
return new SparseInstance(1.0,values,indices,1000000);
}
private void getTrainingDataset(final String INPUT_FILENAME)
{
try{
ArffLoader trainingLoader = new ArffLoader();
trainingLoader.setSource(new File(INPUT_FILENAME));
inputDataset = trainingLoader.getDataSet();
}catch(IOException ex)
{
System.out.println("Exception in getTrainingDataset Method");
}
System.out.println("dataset "+inputDataset.numAttributes());
}
private Instances createInstances(final String INSTANCES_NAME)
{
//create an Instances object with initial capacity as zero
Instances instances = new Instances(INSTANCES_NAME,attributeList,0);
//sets the class index as the last attribute
instances.setClassIndex(instances.numAttributes()-1);
return instances;
}
public static void main(String[] args) throws Exception
{
Classificatore wekaTutorial = new Classificatore();
wekaTutorial.trainClassifier("training_set_prova_tent.arff");
wekaTutorial.testClassifier("testing.arff");
}
public Classificatore()
{
attributeList = new ArrayList<Attribute>();
initialize();
}
private void initialize()
{
featureWords= new ArrayList<String>();
featureMap = new TreeMap<>();
classValues= new ArrayList<String>();
classValues.add("politica");
classValues.add("sport");
classValues.add("musicatvcinema");
classValues.add("infogeneriche");
classValues.add("fattidelgiorno");
classValues.add("statopersonale");
classValues.add("checkin");
classValues.add("conversazione");
}
TESTING METHODS
public void testClassifier(final String INPUT_FILENAME) throws Exception
{
getTrainingDataset(INPUT_FILENAME);
//trainingInstances consists of feature vector of every input
Instances testingInstances = createInstances("TESTING_INSTANCES");
for(Instance currentInstance : inputDataset)
{
//extractFeature method returns the feature vector for the current input
Instance currentFeatureVector = extractFeature(currentInstance);
//Make the currentFeatureVector to be added to the trainingInstances
currentFeatureVector.setDataset(testingInstances);
testingInstances.add(currentFeatureVector);
}
try {
//Classifier deserialization
classifier = (Classifier) weka.core.SerializationHelper.read("NaiveBayes.model");
//classifier testing code
for(Instance testInstance : testingInstances)
{
double score = classifier.classifyInstance(testInstance);
double[] vv= classifier.distributionForInstance(testInstance);
for(int k=0;k<vv.length;k++){
System.out.println("distribution "+vv[k]); //this are the probabilities of the classes and as result i get 1.0 in one and 0.0 in all the others
}
System.out.println(testingInstances.attribute("Class").value((int)score));
}
} catch (Exception ex) {
System.out.println("Exception in testing the classifier."+ex);
}
}
I want to create a text classifier for short messages, this code is based on this tutorial http://preciselyconcise.com/apis_and_installations/training_a_weka_classifier_in_java.php . The problem is that the classifier predict the wrong class for almost every message in the testing.arff because the probabilities of the classes are not correct. The training_set_prova_tent.arff has the same number of messages per class.
The example i'm following use a featureWords.dat and associate 1.0 to the word if it is present in a message instead I want to create my own dictionary with the words present in the training_set_prova_tent plus the words present in testing and associate to every word the number of occurrences .
P.S
I know that this is exactly what can i do with the filter StringToWordVector but I haven't found any example that exaplain how to use this filter with two file: one for the training set and one for the test set. So it seems easier to adapt the code I found.
Thank you very much
It seems like you changed the code from the website you referenced in some crucial points, but not in a good way. I'll try to draft what you're trying to do and what mistakes I've found.
What you (probably) wanted to do in extractFeature is
Split each tweet into words (tokenize)
Count the number of occurrences of these words
Create a feature vector representing these word counts plus the class
What you've overlooked in that method is
You never reset your featureMap. The line
Map<Integer,Double> featureMap = new TreeMap<>();
originally was at the beginning extractFeatures, but you moved it to initialize. That means that you always add up the word counts, but never reset them. For each new tweet, your word count also includes the word count of all previous tweets. I'm sure that is not what you wanted.
You don't initialize featureWords with the words you want as features. Yes, you create an empty list, but you fill it iteratively with each tweet. The original code initialized it once in the initialize method and it never changed after that. There are two problems with that:
With each new tweet, new features (words) get added, so your feature vector grows with each tweet. That wouldn't be such a big problem (SparseInstance), but that means that
Your class attribute is always in another place. These two lines work for the original code, because featureWords.size() is basically a constant, but in your code the class label will be at index 5, then 8, then 12, and so on, but it must be the same for every instance.
indices[i] = featureWords.size();
values[i] = (double) classValues.indexOf(inputInstance.stringValue(1));
This also manifests itself in the fact that you build a new attributeList with each new tweet, instead of only once in initialize, which is bad for already explained reasons.
There may be more stuff, but - as it is - your code is rather unfixable. What you want is much closer to the tutorial source code which you modified than your version.
Also, you should look into StringToWordVector because it seems like this is exactly what you want to do:
Converts String attributes into a set of attributes representing word occurrence (depending on the tokenizer) information from the text contained in the strings. The set of words (attributes) is determined by the first batch filtered (typically training data).

Retrieve user account

I used the following coding to display user accounts in my domain.But in that coding it display only first 100 records.But in my domain nearly 500 users account.I don't know what problem in this coding
import java.net.URL;
import java.util.List;
import com.google.gdata.client.appsforyourdomain.UserService;
import com.google.gdata.data.appsforyourdomain.provisioning.UserEntry;
import com.google.gdata.data.appsforyourdomain.provisioning.UserFeed;
public class Readuser {
public int i3;
public String rn[]=new String[100];
public void read(){
try
{
// Create a new Apps Provisioning service
UserService myService = new UserService("My Application");
myService.setUserCredentials(admin,password);
// Get a list of all entries
URL metafeedUrl = new URL("https://www.google.com/a/feeds/"+domain+"/user/2.0/");
System.out.println("Getting user entries...\n");
UserFeed resultFeed = myService.getFeed(metafeedUrl, UserFeed.class);
List<UserEntry> entries = resultFeed.getEntries();
for(i3=0; i3<entries.size(); i3++) {
UserEntry entry = entries.get(i3);
rn[i3]= entry.getTitle().getPlainText();
System.out.println(rn[i3]);
}
System.out.println("\nTotal Entries: "+entries.size());
}
catch(Exception e) { System.out.print(e);}
}
public static void main(String args[])
{
Readuser ru=new Readuser();
ru.read();
}
}
You only allocate 100 entries.
public String rn[]=new String[100];
Hint from your code : public String rn[]=new String[100];
Do you really need to have i3 and rn as class members ? Do you really need rn ? A List seems more comfortable as an Object than a String[].
There is no need for the string array (String[]).
Arrays are fixed size; and in this case you have allocated 100 "slots" for Strings, and when You try to assign a string to position 100 ( you know, the 101:th string) it fails.
You catch an exception in the end. Print the stack trace to find out whats going on
catch(Exception e) {
e.printStackTrace();
}
Learn to read it an find out what is says... However you should not catch the exception in this method. It is better to abort whatever the program was doing. Catch it in your main method - just printing or logging it is fine, so that you can correct the programming error.
Anyway; The result you get is a List of user entries. Lists are part of the (java.util)collections framework. Collections have a lot of features; in this case you want to iterate over all entries in the list. You can do this by using the iterator() method -read the javadoc...OR you can use for-loop syntactic sugar for doing this:
for( UserEntry user : entries ) {
// user is the current UserEntry
System.out.println(user.getTitle().getPlainText());
}
The variables i3 and rn are no good... They shouldn't be class variables, and if you need "temporary" variables, define them close to where you are going to use them.
As for naming of variables, a name like "entry" is less useful than "user". Actually a class called UserEntry should probably be called just User, but I don't know about this API, so...

Categories

Resources