Reading statistics from a file - java
One of the homework assignments my instructor gave me was a baseball statistics program. It reads from a file called stats.dat, which contains the name of a baseball player's name and a list of what happened when they were at the bat. It reads and prints their name and the amount of outs(o), hits(h), walks(w), and sacrifice flies(s) that they have. This is what the file contains:
Willy Wonk,o,o,h,o,o,o,o,h,w,o,o,o,o,s,h,o,h
Shari Jones,h,o,o,s,s,h,o,o,o,h,o,o,o
Barry Bands,h,h,w,o,o,o,w,h,o,o,h,h,o,o,w,w,w,h,o,o
Sally Slugger,o,h,h,o,o,h,h,w
Missy Lots,o,o,s,o,o,w,o,o,o
Joe Jones,o,h,o,o,o,o,h,h,o,o,o,o,w,o,o,o,h,o,h,h
Larry Loop,w,s,o,o,o,h,o,o,h,s,o,o,o,h,h
Sarah Swift,o,o,o,o,h,h,w,o,o,o
Bill Bird,h,o,h,o,h,w,o,o,o,h,s,s,h,o,o,o,o,o,o
Don Daring,o,o,h,h,o,o,h,o,h,o,o,o,o,o,o,h
Jill Jet,o,s,s,h,o,o,h,h,o,o,o,h,o,h,w,o,o,h,h,o
So far I have the basic idea down, even though I don't quite understand what each line is doing(I modified some code of a program in the book my class is reading that prints a URL that's in a text file and then prints out each part of the url that's separated by a /). I have it so that the program prints out the player's name, but I'm stumped on how to print out the amount of hits, outs, walks, and sacrifice flies they get. So far it's reading 1 character out of the line, then it goes down to the next player and prints out 2, then 3, etc. Here's the code I have for it so far:
import java.util.Scanner;
import java.io.*;
public class BaseballStats
{
public static void main(String [] args) throws IOException
{
int hit = 0, walk = 0, sac = 0, out = 0, length = 0, wholeLength = 0;
Scanner fileScan, lineScan, statScan;
String fileName, playerName, line, stats, playerStats;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the name of the file: ");
fileName = scan.nextLine();
fileScan = new Scanner(new File(fileName));
while (fileScan.hasNext())
{
System.out.println();
line = ("Player: " + fileScan.nextLine());
wholeLength = line.length();
lineScan = new Scanner(line);
lineScan.useDelimiter(",");
stats = lineScan.next();
statScan = new Scanner(stats);
statScan.useDelimiter(",");
while (statScan.hasNext())
{
System.out.println(statScan.next());
length = stats.length() - 1;
for (int i = 0; i < length; i++)
{
if (stats.charAt(i) == 'h')
hit++;
else if (stats.charAt(i) == 'o')
out++;
else if (stats.charAt(i) == 'w')
walk++;
else if (stats.charAt(i) == 's')
sac++;
}
}
System.out.println("Hits: " + hit + "\nOuts: " + out + "\nWalks: " + walk + "\nSacrifice flies: " + sac);
}
}
}
(I'm having a hard time getting the last part of the last statement in my code to appear correctly in the editor, sorry if it looks a bit weird) I have been wondering what's wrong and I can't figure it out so far. Is there anything to get me on the right track?
If looks like you're creating one Scanner instance too many:
You use the first Scanner: fileScan to read one line at a time and assign this to line.
You then create a Scanner: lineScan to read over the line one field at a time.
However, you only read the first token from lineScan and then create a third Scanner instance: statsScan. Rather than do this, you simply need to read all the tokens from lineScan, storing the first as the person's name and processing the subsequent tokens as statistics.
One other thing I'd advise is to create a dedicated class to hold the person's name and statistics and implement toString() on this class to produce a sensible String representation; e.g.
public class Player {
private final String name;
private int hit, out, walk, sac;
public int getNumHits() {
return hit;
}
public int incrementNumHits() {
return ++hit;
}
// TODO: Implement other getter and increment methods.
public String toString() {
return String.format("%s. Hits: %d, Outs: %d, Walks: %d, Sacrifice flies: %d",
name, hit, out, walk, sac);
}
}
By implementing toString() you simply need to create and populate your Player class with statistics and then print it out; e.g.
Player player = new Player("Jim");
player.incrementNumHits();
// etc.
System.out.println(player);
Related
Currency Exchanger
I am trying to write a code that will exchange between AED,MYR,USD. I got to the following code and I cant fix the error. It looked like the system.in isn't closing so I wrote the inclose(). But I still get the same results. My problem might be something else and am not seeing it. EDIT: this is the current code with changes. import java.util.Scanner; public class CurrencyConverter { protected static long amount; static long Namount ; static int commesion; static String to; public static void main( String[] args ) { CurrencyConverterM MSg=new CurrencyConverterM(); CurrencyConverterM account1 = new CurrencyConverterM( ); String from ; for(int i=0 ;i<3; i++) { System.out.println("Please enter your currency (USD, AED, or MYR only): "); Scanner in = new Scanner( System.in ); from = in.nextLine(); System.out.println("What currency do you want?: "); String to = in.nextLine(); System.out.println("How much you want to convert?: "); amount= in.nextLong(); //in.close(); if ("USD".equals(from)) { amount=((long) (amount*0.27)); amount=account1.converter(to, amount); } else if ("MYR".equals(from)) { amount=((long) (amount * 1.14)); amount =account1.converter(to, amount); } else { if(mmount >= 900) { Namount = (amount-50); commesion =50; } else { Namount = (amount - 10); commesion = 10; } } System.out.println(MSg.getMsg()); } } } the output should be as follows. asking for current currency: asking to what currency u want it: asking about the amount. am converting any amount to AED so I make it the main unit, then converting to the wished unit. EDIT public class CurrencyConverterM extends CurrencyConverter { long am; #SuppressWarnings("static-access") long converter (String to,long amount) { if ("MYR".equals(to)) { am=(super.amount*=0.88); } else if ("MYR".equals(to)) { am=(super.amount*=3.7); } return am ; } #SuppressWarnings("static-access") public String getMsg() { return ("Thank you. The converted amount is "+(super.amount) + ". We will take" +super.commesion + " commission, and you will get "+ super.Namount); } } before it didn't read the user's input, now its not converting the values. I tried to print out my vales after each calculation but it looks like that the variable am is not being calculated correctly and its being multiplied by a 0 or divided by one ( the last result is always 0 ) but the amount that is in the main class is not 0 and its not converted to AED as well. So I am getting this :Thank you. The converted amount is 0.0 1000.0. We will take50 commission, and you will get 0.0
String comparison is wrong. from=="MYR" should be from.equals("MYR") rather I would recommend equalsIgnoreCase which is not case sensitive.
You should call scanner.nextLine() (in.nextLine()) and not in.toString() Also you can use the same scanner and not to create 3 different scanners. See the following part of your code updated with one Scanner (in): System.out.println("Please enter your currency (USD, AED, or MYR only): "); Scanner in = new Scanner( System.in ); from = in.nextLine(); System.out.println("What currency do you want?: "); String to = in.nextLine(); System.out.println("How much you want to convert?: "); amount= in.nextLong(); System.out.println(from + " " + to); in.close(); by doing in.nextLine() you read the next line of user input. From java 8 javadocs: nextLine public String nextLine() Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line. Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present. The above will solve the issue that no input is read by your code. Later you will have issues comparing the String user entered: from=="USD" should be changed to "USD".equals(from) Tip: Prefer to use "String".equals(variable) to avoid null pointer exceptions when variable is null.
Java, Reading two different types of variables from a file and using them as objects later
I working on a project that is based on reading a text from a file and putting it as objects in my code. My file has the following elements: (ignore the bullet points) 4 Christmas Party 20 Valentine 12 Easter 5 Halloween 8 The first line declares how many "parties" I have in my text file (its 4 btw) Every party has two lines - the first line is the name and the second one is the number of places available. So for example, Christmas Party has 20 places available Here's my code for saving the information from the file as objects. public class Parties { static Scanner input = new Scanner(System.in); public static void main(String[] args) throws FileNotFoundException { Scanner inFile = new Scanner(new FileReader ("C:\\desktop\\file.txt")); int first = inFile.nextInt(); inFile.nextLine(); for(int i=0; i < first ; i++) { String str = inFile.nextLine(); String[] e = str.split("\\n"); String name = e[0]; int tickets= Integer.parseInt(e[1]); //this is where it throw an error ArrayIndexOutOfBoundsException, i read about it and I still don't understand Party newParty = new Party(name, tickets); System.out.println(name+ " " + tickets); } This is my SingleParty Class: public class SingleParty { private String name; private int tickets; public Party(String newName, int newTickets) { newName = name; newTickets = tickets; } Can someone explain to me how could I approach this error? Thank you
str only contains the party name and splitting it won't work, as it won't have '\n' there. It should be like this within the loop: String name = inFile.nextLine(); int tickets = inFile.nextInt(); Party party = new Party(name, tickets); // Print it here. inFile().nextLine(); // for flushing
You could create a HashMap and put all the options into that during your iteration. HashMap<String, Integer> hmap = new HashMap<>(); while (sc.hasNext()) { String name = sc.nextLine(); int tickets = Integer.parseInt(sc.nextLine()); hmap.put(name, tickets); } You can now do what you need with each entry in the HashMap. Note: this assumes you've done something with the first line of the text file, the 4 in your example.
nextLine() returns a single string. Consider the first iteration, for example, "Christmas Party". If you split this string by \n all you're gonna get is "Christmas Party" in an array of length 1. Split by "blank space" and it should work.
How to use a Movie Review file to print out sentiment averages for words in another file?
I am working on a project that has many different parts and methods. For this one specific part I need to ask the user for the name of a file that contains a set of words, one per line. (see attached) Then I need to compute the average score/sentiment of the word by comparing it to a movieReview file that scores the sentiment of words. (see attached) [Edit] : I have not gotten my code to take the first line of the wordList file, search through the movieReview file for the word, and find the average score of the word. And after the search is complete, move onto the next word. However, it is printing NaN for the rest of the words after the first, "mechanical" Example: The first word in the wordList file is "mechanical". Mechanical is found in the movieReview file 6 times and the total score is 4. The average sentiment for the word "mechanical" is .666666666. How can I make my code so the loop continues and finds the average for every single word and prints it out? Sorry if this sound confusing, let me know if I need to clarify. Also, I am a very beginner coder so please try to not use difficult concepts. (Also, it was said using an array or buffer wasn't needed) Movie Review File : http://nifty.stanford.edu/2016/manley-urness-movie-review-sentiment/movieReviews.txt Content of Word List file(txt): mechanical car soulless style family wonderful historical nor strong slapstick complicated provoking interest cast witty muted sentiment narrative refreshing preachy horrible resolutely terrible dialogue incoherent spend words moving devoid indulgent dull value barely always dog tale hardly unfocused formulaic eccentric quirky unpredictable tears writing import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class methodThree { public static void main (String [] args) throws FileNotFoundException { Scanner in = new Scanner(System.in); System.out.println("Enter the name of the file with words you want to score: "); String inputFileName = in.next(); File inputFile = new File(inputFileName); while(!inputFile.exists()) { System.out.println("Please enter a valid file name:"); inputFile = new File(in.next()); } Scanner wordFile = new Scanner (inputFile); File inputMovie = new File("movieReviews.txt"); Scanner movieReview = new Scanner (inputMovie); String reviewText; int reviewScore; while (wordFile.hasNextLine()) { int count = 0; double total = 0; String word = wordFile.nextLine(); while (movieReview.hasNext()) { reviewScore = movieReview.nextInt(); reviewText = movieReview.nextLine(); if (reviewText.contains(word)) { count++; total = total + reviewScore; } } double average = (total / count); System.out.println (word + " " + average); } } }
So what you basically want to do is repeat this code for every line in the wordfile? int count = 0; double total = 0; String word = wordFile.nextLine(); while(movieReview.hasNext()){ reviewScore = movieReview.nextInt(); reviewText = movieReview.nextLine(); if (reviewText.contains(word)) { count++; total = total + reviewScore; } } double average = (total / count); System.out.println(average); if thats the case you could surround it with another while loop. The loop must run for every line in wordFile, so it's more or less the same loop as your movieReview.hasNext() loop. while(wordFile.hasNext()){ int count = 0; ... } The loop runs as long as wordFile has another word to score.
reading files from java?
I have an assignment where I have to make a simple banking application. i need to store the customers information in a file with first and last name,customer id and balance. i then need to create a menu option to check balance,withdraw,deposit and quit. The problem i am currently having is trying to show the balance when they user wants to check balance. balance is on the forth line of my file and i am not sure how to only show the fourth line and then be able to use that number to add or subtract a number. I am trying to do this in case 1 in the switch statement. Any hints would be appreciated. import java.util.Scanner; import java.text.DecimalFormat; import java.io.*; public class bank { public static void main(String[] args) throws IOException { String fileName; // stores the name of the file String bankCustomer; // used to display the customers bank information int menuOption = 0; // allows the user to enter a number so they can select what they want to do Scanner keyboard = new Scanner(System. in ); // enter the file name to see customer information System.out.print("enter file name "); fileName = keyboard.nextLine(); File file = new File(fileName); Scanner inputFile = new Scanner(file); // read customer information from file i need this while (inputFile.hasNext()) { bankCustomer = inputFile.nextLine(); System.out.println(bankCustomer); } System.out.println("Please enter the number for the following:\n 1) Balance \n 2) Deposit + \n 3) Withdrawal \n 4) Quit "); menuOption = keyboard.nextInt(); switch (menuOption) { case 1: // need to show balance how do i do that? while (inputFile.hasNext()) { bankCustomer = inputFile.nextLine(); System.out.println(bankCustomer); } break; default: System.out.println("Invalid choice"); } inputFile.close(); } }
There are many ways to do this. One way is to read all the lines from the Scannerobject and convert it into a List (ArrayList) or String Array. That is each item in the Array or List corresponds to a line of the file. The index of the list or array will then provide with the contents of the that particular file. ============================================================================= Ok based on your comment, now that you still have not learn Arrays you can do it the way your reading your bank Customer name String bankCustomer = inputFile.nextLine(); //Assuming second line contains account number String bankAccountNumber = inputFile.nextLine(); // Assuming third line contains account type. String bankAccountType = inputFile.nextLine(); // Fourth line has your account balance String bankAccountBalanceStr = inputFile.nextLine(); double bankAccountBalance = 0d; if(null != bankAccountBalanceStr && 0 > bankAccountBalanceStr.length()){ bankAccountBalance = Double.parseDouble(bankAccountBalanceStr); } Of course the answer is just indicative and does not do all the null checks and assumes the file format is exactly as you have told.
Without recreating your data and code, it appear that you are reading the entire line of data to bankcustomer. If your data file structure IS comma-delimited, you could then split the line into components. Define a data class public static class customer { public String first; public String last; public String customer_i; public double balance: } Once you have the line translated into the data class, you can reference each by: balance = customer.balance. etc. This is approximate but I hope it helps.
The easiest way is to simply read and ignore the first three lines, by doing something like: for (int i = 0; i < 3; i++) inputFile.nextLine(); and then reading the fourth line as an integer with the Integer.parseInt () method. int total = Integer.parseInt (inputFile.nextLine ()); Note that in both snippets error and exception handling was omitted.
You can either read 3 lines and not save their values, or search each line for a keyword: int balance; if(!bankCustomer.indexOf("balance") != -1) { balance = Integer.parseInt(bankCustomer); }
arraylist isn't printing out correctly in a separate method for loop? wrapper class or loops to blame?
for my project, i have an arraylist for the user to input whatever names they want in one method as long as it isn't stop. then in a separate method, the values i just inputted have to be called out again, so i can input more information for each name. example: enter names: name: bob name: joe name: Stop this triggers another method to prompt more info: bob: enter age: enter address: joe: enter age: enter address: However, right now, the arraylist isn't printing out correctly, and i'm getting repeats of certain names, while other names don't show up in the second method. Also, the loop in the second method doesn't end. i enter in info for the names i entered, but i keep getting prompted with "name:" and no actual arraylist value. I suspect something is wrong with my loops, but i don't quite know how to fix it? I also thought that maybe the problem has something to do with how i'm using a wrapper to put in values into the arraylist, but i don'tknow how to fix that. in the second method, I've tried swapping the countervariable to keep track of the order in the Array List with a separate counter in the second method, but it doesn't seem to make a difference. In the first method, i've tried swapping the loop with different a boolean while loop, with a straight up while (!input.equals("Stop")), a for loop counter inside of the previous two options, if loops, and some combination of the above. here is my code Scanner console = new Scanner(System.in); private ArrayList<Directory> nameList; //i have to use object oriented programming to store values in the Directory Class public int i; first method: private void addName() { Scanner LocalInput = new Scanner(System.in); Directory buffer = null; String ID = null; System.out.println("Enter Station Designations Below, Enter Stop to quit"); boolean breaker = false; while(breaker ==false) { System.out.print("Name: "); ID = (LocalInput.nextLine()); if(ID.equals("Stop")) breaker = true; else buffer = new Directory(ID); nameList.add(buffer); } } second method: private void getInfo() { Scanner LocalInput = new Scanner(System.in); Directory buffer; buffer = nameList.get(i); double age; String address; System.out.println("Enter Temperatures below..."); System.out.println("" + nameList.get(i)); for (i = 0; i < nameList.size(); i++) { System.out.println("Name: " + buffer.GetID()); //there's a getter and setter in the Directory class System.out.println( "Age:\t"); age = LocalInput.nextDouble(); System.out.print( "Address:\t"); address = LocalInput.nextLine(); buffer= new Directory(age, address); nameList.add(buffer); } }
Critique of first method I haven't looked closely yet, but I strongly suspect this is the problem: if(ID.equals("Stop")) breaker = true; else buffer = new Directory(ID); nameList.add(buffer); You appear to be expecting the last statement only to be executing when ID is not equal to "Stop", but actually it's always going to execute. Unlike (say) Python, whitespace is irrelevant in Java. If you statements to be considered as a block, you need braces: if(ID.equals("Stop")) breaker = true; else { buffer = new Directory(ID); nameList.add(buffer); } Personally I would put braces around both parts: if (ID.equals("Stop")) { breaker = true; } else { buffer = new Directory(ID); nameList.add(buffer); } ... and quite possibly get rid of the somewhat-irrelevant buffer variable: if (ID.equals("Stop")) { breaker = true; } else { nameList.add(new Directory(ID)); } I'd also get rid of the breaker variable, and limit the scope of ID (changing its name, too, to comply with normal conventions) with a result of: while (true) { System.out.print("Name: "); string id = LocalInput.nextLine(); if (id.equals("Stop")) { break; } nameList.add(new Directory(ID)); } Critique of second method This is really odd at the moment. It's not at all clear where the i variable is declared, or why you only fetch buffer once, or why you're just adding to the existing list rather than mutating the existing object. I suspect you really want: for (Directory entry : nameList) { System.out.println("Name: " + entry.GetID()); System.out.println( "Age:\t"); double age = LocalInput.nextDouble(); entry.setAge(age); System.out.print( "Address:\t"); String address = LocalInput.nextLine(); entry.setAddress(address); } Note that your current loop will always continue until i equals nameList.size() - but you're always increasing the size in the loop, so you'll never terminate.
private void getInfo() { Scanner LocalInput = new Scanner(System.in); double age; String address; for (Directory name : nameList) { System.out.println("Name: " + name .GetID()); System.out.println( "Age:\t"); double age = LocalInput.nextDouble(); name.setAge(age); System.out.print( "Address:\t"); String address = LocalInput.nextLine(); name.setAddress(address); } } get method should be like this and Add must be - private void addName() { Scanner LocalInput = new Scanner(System.in); Directory buffer = null; String ID = null; System.out.println("Enter Station Designations Below, Enter Stop to quit"); boolean breaker = false; while(breaker ==false) { System.out.print("Name: "); ID = (LocalInput.nextLine()); if(ID.equals("Stop")) breaker = true; else { buffer = new Directory(ID); nameList.add(buffer); } } }
Consider using the break keyword, then you don't need the breakerflag and the else branch: while(true) { System.out.print("Name: "); ID = (LocalInput.nextLine()); if(ID.equals("Stop")) break; buffer = new Directory(ID); nameList.add(buffer); } Sorry was already posted...