I have a homework assignment to read data from a file which contains names and scores per game of basketball players. The program is supposed to output the names and scores of the players, as well as tally each player's average score per game, and finally display the player with the highest average. I am currently stuck on trying to get the average and a newline character for each player.
Here is a pic of the input file I am reading the data from.
and here is my code:
import java.util.Scanner;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
public class BasketballTeam
{
public static void main(String[] args) throws IOException
{
File f = new File("BasketballData.txt");
if (f.exists())
{
Scanner input = new Scanner(f);
int games = 0;
int totalScore = 0;
double avg = 0.0;
while (input.hasNext())
{
String s = input.next();
System.out.printf("%-9s", s);
int a = input.nextInt();
while (input.hasNextInt())
{
if (a == -1)
{
avg = (double)totalScore/games;
System.out.printf("%14s%.2f\n", "Average of ", avg);
games = 0;
totalScore = 0;
s = input.next();
}
else
{
System.out.printf("%5s", a);
games++;
totalScore = totalScore + a;
a = input.nextInt();
}
}
}
}
}
}
When I run the program, my output is just a single line that looks like:
Smith 13 19 8 12Badgley 5Burch 15 18 16Watson......and so on
Why am I not getting any newline characters or my average? I want my output to look like this:
Smith 13 19 8 12 Average of 13
Badgley 5 Average of 5
Burch 15 18 16 Average of 16.33
.....and so on
Thanks in advanced for any suggestions/corrections.
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class BasketballTeam
{
public static void main(String[] args) throws IOException
{
File f = new File("BasketballData.txt");
if (f.exists())
{
Scanner input = new Scanner(f);
int games = 0;
int totalScore = 0;
double avg = 0.0;
while (input.hasNext())
{
String s = input.next();
System.out.printf("%-9s", s);
while (input.hasNextInt())
{
int a = input.nextInt();
if(a != -1)
{
System.out.printf("%5s", a);
games++;
totalScore = totalScore + a;
}
}
avg = (double)totalScore/games;
System.out.printf("%14s%.2f\n", "Average of ", avg);
games = 0;
totalScore = 0;
System.out.println();
}
input.close();
}
}
}
This is what you are looking for. You don't even need the -1 at the end of each line in the file you can get rid of that if you want unless it is part of the specification. It will work without the -1. Your inner loop you just want to add up your totals then outside of the inner loop get your average and display. Then reset your variables. You were pretty close just needed to change a couple things. If you have any questions on how this works just ask away. Hope this helps!
Try
avg = ((double)totalScore/(double)games);
and replace \n with \r\n:
System.out.printf("%14s%.2f\r\n", "Average of ", avg);
I would highly recommend using a FileReader:
File file = new File("/filePath");
FileReader fr = new FileReader(file);
Scanner scanner = new Scanner(fr);
//and so on...
In this line a = input.nextInt(), you already advance to the next int, so the test input.hasNextInt() will be false when you reach -1.
One possible solution is to change the loop to:
while (input.hasNext()) {
String s = input.next();
System.out.printf("%-9s", s);
int a = 0;
while (input.hasNextInt()) {
a = input.nextInt();
if (a == -1) {
avg = (double) totalScore / games;
System.out.printf("%14s%.2f\n", "Average of ", avg);
games = 0;
totalScore = 0;
} else {
System.out.printf("%5s", a);
games++;
totalScore = totalScore + a;
}
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
public static void inputThenPrintSumAndAverage (){
Scanner scanner = new Scanner(System.in);
int count =0;
int sum =0 ;
long average = 0;
boolean isAnInt = scanner.hasNextInt();
while (true) {
count++;
int number = scanner.nextInt();
if (isAnInt) {
sum+=number;
average = Math.round((sum/count));
} else {
break;
}
scanner.nextLine();
}
System.out.println("SUM = "+sum+ " AVG = "+average);
scanner.close();
}
When I am giving it a string it gives exception and doesn't even execute the "sum and avg" values. How can I change the code to make it work? If I have some wrong conceptual knowledge please help me understand the concept. Thank you.
You do not need Scanner#hasNextInt for Scanner(System.in). Also, you do not need the check, if (isAnInt). Instead, you should put a try-catch block.
You should not close Scanner(System.in); otherwise, there is no way to open it again without restarting the JVM.
Both the above thing are required when you use the Scanner for a File.
Demo:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// Test
inputThenPrintSumAndAverage();
}
public static void inputThenPrintSumAndAverage() {
Scanner scanner = new Scanner(System.in);
int count = 0;
int sum = 0;
long average = 0;
while (true) {
try {
int number = scanner.nextInt();
sum += number;
count++;
} catch (InputMismatchException e) {
break;
}
}
average = Math.round((sum / count));
System.out.println("SUM = " + sum + " AVG = " + average);
}
}
A sample run:
2
3
5
8
abc
SUM = 18 AVG = 4
Note: you can get a better precision for average if you declare it as double and store the floating-point calculation into it without rounding e.g.
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// Test
inputThenPrintSumAndAverage();
}
public static void inputThenPrintSumAndAverage() {
Scanner scanner = new Scanner(System.in);
int count = 0;
int sum = 0;
double average = 0;
while (true) {
try {
int number = scanner.nextInt();
sum += number;
count++;
} catch (InputMismatchException e) {
break;
}
}
average = (double) sum / count;
System.out.println("SUM = " + sum + " AVG = " + average);
}
}
A sample run after this change:
2
3
5
8
abc
SUM = 18 AVG = 4.5
It will also be useful for you to understand this concept.
this is my first question in this community as you can see I'm a beginner and I have very little knowledge about java and coding in general. however, in my beginner practices, I came up with a little project challenge for myself. as you can see in the figure, the loop starts and it prints out the number that is given to it through the scanner. the problem with my attempt to this code is that it gives me the output value as soon as I press enter. what I want to do is an alternative of this code but I want the output values to be given after the whole loop is done all together.
figure
So, basically what I want is to make the program give me the input values together after the loop ends, instead of giving them separately after each number is put.
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
calc(); }
public static int calc (){
Scanner scan = new Scanner(System.in);
int count = 1;
int pass = 0;
int notpass = 0;
System.out.println("how many subjects do you have? ");
boolean check = scan.hasNextInt();
int maxless = scan.nextInt();
if (check){
while(count <= maxless ){
System.out.println("Enter grade number " + count);
int number = scan.nextInt();
System.out.println("grade number" + count + " is " + number);
if (number >= 50){
pass++;
}else{
notpass++;
}
count++;
}
System.out.println("number of passed subjects = " + pass);
System.out.println("number of failed subjects = " + notpass);
}else{
System.out.println("invalid value!");
} return pass;
}
}
I think what you want to do is create an array of int numbers.
It would be something like this:
import java.util.Scanner;
public class Application {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int maxless = 5;
int[] numbers = new int[maxless];
int count = 0, pass = 0, notPass = 0;
while(count < maxless){
System.out.println("Enter grade number " + (count + 1) + ":");
numbers[count] = scan.nextInt();
if(numbers[count] >= 50){
pass++;
}
else{
notPass++;
}
count++;
}
for(int i=0; i<maxless; i++){
System.out.println("Grade number " + (i + 1) + " is " + numbers[i]);
}
}
}
The output is the following:
Enter grade number 1:
90
Enter grade number 2:
76
Enter grade number 3:
54
Enter grade number 4:
67
Enter grade number 5:
43
Grade number 1 is 90
Grade number 2 is 76
Grade number 3 is 54
Grade number 4 is 67
Grade number 5 is 43
When dealing with arrays, just remember that the indexation begins at 0. You can read more about arrays here: http://www.dmc.fmph.uniba.sk/public_html/doc/Java/ch5.htm#:~:text=An%20array%20is%20a%20collection,types%20in%20a%20single%20array.
A tip: it's gonna be easier to help if you post the code on your question as a text, not an image, so we can copy it and try it on.
Approach 1 :
You can use ArrayList from Collection Classes and store the result there and after the loop is completed, just print the array in a loop.
Example :
//Import class
import java.util.ArrayList;
//Instantiate object
ArrayList<String> output = new ArayList();
while(condition){
output.add("Your data");
}
for(i = 0; i < condition; i++){
System.out.println(output.get(i));
}
Approach 2 :
Use StringBuilder class and append the output to the string, after the loop is completed, print the string from stringbuilder object.
Example :
//import classes
import java.util.*;
//instantiate object
StringBuilder string = new StringBuilder();
while(condition){
string.append("Your string/n");
}
System.out.print(string.toString());
Approach 3 : (As mentioned by Sarah)
Use arrays to store the result percentage or whatever and format it later in a loop. (Not a feasible approach if you want to store multiple values for the same student)
Example :
int studentMarks[] = new int[array_size];
int i = 0;
while(condition){
studentMarks[i++] = marks;
}
for(int j = 0; j < i; j++)
System.out.println("Marks : " + studentMarks[j]);
I am having trouble with a program that looks to compute the chance of someone winning a contest that they have a 1 in 5 chance of winning. It is a simulation that repeats this 1000 times. The current loop iterates once correctly but just outputs zero to the file for all other loops and I can't figure out why.
import java.util.Scanner;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.File;
public class BottleCapPrize
{
public static void main (String [ ] args) throws IOException
{
//establishing scanner and variables
Scanner in = new Scanner(System.in);
int minimumTrials = 1000;
int enteredTrials = 0;
int won = 0;
int triesToWin = 0;
double totalTries = 0;
int winningValue = 0;
//establishes the number of trials and sais if it is less than 1000
while(enteredTrials < minimumTrials)
{
System.out.println("Please enter a number of trials greater than 1000: ");
enteredTrials = in.nextInt();
if(enteredTrials >= minimumTrials)
{
System.out.println("You enetred " + enteredTrials + " trials.");
}
else
{
System.out.println("You entered an incorrect number of trials.");
}
}
//establishes file to write to
PrintWriter outFile = new PrintWriter(new File("prizeResults.txt"));
//writes to these files the amount of tries it takes to get the prize 1000 times
for (int loop = 1; loop <= enteredTrials; loop++)
{
while(won != 1)
{
winningValue = (int)((Math.random() * 5.0) + 1.0);
if(winningValue == 1)
{
won ++;
triesToWin ++;
}
else
{
triesToWin ++;
}
}
winningValue = 0;
outFile.println(triesToWin);
triesToWin = 0;
}//end of for loop
outFile.close ( ); //close the file when finished
//finds the average number of tries it took
File fileName = new File("prizeResults.txt");
Scanner inFile = new Scanner(fileName);
while (inFile.hasNextInt())
{
totalTries = totalTries + inFile.nextInt();
}
double averageTries = totalTries/enteredTrials;
//tells the user the average
System.out.println("You would have to by an average of " + averageTries + " bottles to win.");
}//end of main method
}//end of class
You are not resetting won back to zero. Thus after the first time, when you increment won to 1, the while loop ends, and then in each subsequent for loop, it skips the while loop and prints value of triesToWin which you set back to zero.
Try adding
won = 0;
after writing to the file.
I'm new to Java, and struggling with something I've never had trouble with in the past. For whatever reason, I can't scan an int (or a double) in my code, but I can scan a string just fine. I'm posting the snippet where my scanner isn't functioning, please let me know if I should include the rest of the program.
import java.util.Scanner;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
public class DZP3
{
public static void main(String[] args) throws IOException
{
announce();
Scanner scan = new Scanner(System.in);
//Prompt user for input file
System.out.println("Greetings! Please enter the filename of the plaintext olympics data file you'd like to open.");
String txtFilename = scan.nextLine();
//Opens olympics data txt file specified, exits if it does not exist
File medalsInput = new File (txtFilename);
if(!medalsInput.exists())
{
System.out.println("File not found. Reload and try again.");
System.exit(1);
}
//Prompt user for output file
System.out.println("Thanks. Please enter the filename of the plaintext data output file.");
String outputTxt = scan.nextLine();
//Create output file specified
File medalsOutput = new File (outputTxt);
//Prompt user for medal cutoff X value
System.out.println("Thanks. Please enter the minimum number of medals a nation must have earned to be counted for calculation 2 listed above. \nEnter the value, as an integer:");
int medalsCutoff = 0;
medalsCutoff = scan.nextInt();
fileProcessing(medalsInput, medalsOutput, medalsCutoff);
}
}
Near the bottom, medalsCutoff is not accepting any scanned value whatsoever. I've tried putting it in a method other than main, I've tried rearranging it, creating a separate scanner just for it, and a few other things. The debugger shows that, no matter what, I'm stuck on that line of code. What have I done wrong? I'm at a loss.
EDIT: Here's the fileProcessing method, and what comes after. The announce method is just system.out.println.
public static void fileProcessing(File medalsIn, File medalsOut, int medalsMin) throws IOException
{
//Initialize necessary variables and strings
int maxTotMedals = -1;
int natCountMedalsMin = 0;
int natHiScore = -1;
String natName;
String answerOne = "DEFAULT";
int answerTwo = 0;
String answerFour = "DEFAULT";
//Create Printwriter
PrintWriter pw = new PrintWriter(medalsOut);
//Create scanner to read from file, loop until end of file
Scanner filescan = new Scanner(medalsIn);
while (filescan.hasNext())
{
//Initializes medal counting variables at zero, resetting the values with each line
int gCount = 0;
int sCount = 0;
int bCount = 0;
natName = filescan.next();
int lineMedals = 0;
while (lineMedals < 4); //Runs 4 times to cover all four years
{
gCount += filescan.nextInt();
sCount += filescan.nextInt();
bCount += filescan.nextInt();
lineMedals++;
}
int totalMedals = gCount + sCount + bCount;
//Sees if this line's medals have exceeded previous total medal record, if yes, sets country name as answer to question one
if (totalMedals > maxTotMedals)
{
answerOne = natName;
maxTotMedals = totalMedals;
}
if (totalMedals >= medalsMin)
{
natCountMedalsMin++; //For answer two
}
//Score calculation
int natScore = gCount*3;
natScore += sCount*2;
natScore += bCount;
//Compares score to highest score, for answer four
if (natScore > natHiScore)
{
answerFour = natName;
natHiScore = natScore;
}
//Write nation name and score to file
pw.println(natName + " " + natScore);
}
//Define answer two after all countries have been counted
answerTwo = natCountMedalsMin;
//Close output file
pw.close();
//Send results to answer method
answerPrint(answerOne, answerTwo, answerFour, medalsMin, natHiScore);
}
//This method outputs the answers to the user.
public static void answerPrint(String answerEin, int answerZwei, String answerVier, int medalsMini, int HiScore)
{
System.out.println("File read successfully.");
System.out.println("The nation that earned the greatest number of medals is " + answerEin + ".");
System.out.println(answerZwei + " countries earned more than " + medalsMini + " medals.");
System.out.println("The nation with the highest score is " + answerVier + " with a score of " + HiScore + ".");
System.out.println("Thank you for using this program. Until next time!");
}
EDIT 2: This has been solved, I had a stray semicolon in my fileProcessing method that caused an infinite loop. Thank you all for your help.
while (lineMedals < 4);
Above line has a semicolon at the end. It is an infinite loop.
after file creation ,you use this below method
File medalsOutput = new File (outputTxt);
medalsOutput.createNewFile()
in ur code file not got created and exiting via syste.exit(1)
Before this the user inputs an int for numOfTimes. Say it's 5. This will ask the question 5 times. But each time through it will erase the previous value in hrs1. It needs to be a separate variable. So if numOfTimes=5 Then I should get 5 different doubles for "Hour " and 5 different doubles for "Minute ". (assuming the user inputs different times) but they all need to be stored in different variables. How should I do this?
Thank you my question has been answered!
use an array ..
int a[] = new int[5];
for(int i =0;i<5;i++){
a[i] = //your value
}
You just need to put your "calculate average" code outside the for loop. I am not sure exactly how you want to calculate the average. But here are two simple ways.
Method one - keep track of the totals and calculate the basic average.
public class AvgTime {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("How many times? ");
int numOfTimes = in.nextInt();
System.out.println("\n");
double hrTotal = 0;
double minTotal = 0;
for (int i = 1; i <= numOfTimes; i++){
System.out.println("What Time (military time): ");
System.out.print("Hour ");
double hrs1 = in.nextDouble();
System.out.print("Minute ");
double min1 = in.nextDouble();
hrTotal += hrs1;
minTotal += min1;
}
//calculate average
double avdHr1 = hrTotal/numOfTimes;
double timeMin1 = minTotal/numOfTimes;
System.out.println(avgHr1+":"+timeMin1 + " P.M");
}
}
Method 2 - Use lists and iterate twice
public class AvgTime {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("How many times? ");
int numOfTimes = in.nextInt();
System.out.println("\n");
ArrayList<Double> hours = new ArrayList<>();
ArrayList<Double> minutes = new ArrayList<>();
double minTotal = 0;
for (int i = 1; i <= numOfTimes; i++){
System.out.println("What Time (military time): ");
System.out.print("Hour ");
double hrs1 = in.nextDouble();
System.out.print("Minute ");
double min1 = in.nextDouble();
hours.add(hrs1);
minutes.add(min1);
}
//calculate average
double avgHr1 = 0;
double timeMin1 = 0:
for (int i = 0; i < hours.size(); i++) {
double hour = hours.get(i);
double minute = minutes.get(i);
//ToDo: calculate average so far
}
System.out.println(avgHr1+":"+timeMin1 + " P.M");
}
You can use arrays to store the information the user has input. Before the loop, make an array using the new keyword, e.g. double[] hrs=new double[numOfTimes]. In the loop, write to different locations in the array for each input, hrs[i]=in.nextDouble(). You can later read from a position on the array using the syntax 'name[index]', such as 'hrs[2]'. Note that for java and many other languages, arrays start at 0. This means for an array [1,2,3] named arr, arr[1] equals 2 instead of 1. This means it would be best if your for loop was changed from for(int i=1;i<=numofTimes;i++) to 'for(int i=0;i
<SOAPBOX,RANT,HIGHHORSE>
This is more of a code review than a straight answer, but something has been bugging me about newbie questions that I've observed on stackoverrflow.
When developing, I avoid keyboard input like the plague. It is such drudgery, especially with a loop such as in this program. So many newbie questions have user-keyboard input. Why?! It makes development so much more difficult!
I've rewritten your program to add the ability for testing data, completely avoiding the need for user-input during development. When testing is over, just switch the test/live comments around.
I'm sure there's a more elegant way, but this style has worked well for me, and I recommend it.
</SOAPBOX,RANT,HIGHHORSE>
import java.util.*;
import static java.lang.Math.abs;
public class AverageTimeWTestingData {
public static void main(String[] args) {
HourMin24[] ahm = null;
//EXACTLY ONE of the following lines must be commented out
//Test only:
ahm = getTestData();
//Live only:
// ahm = getDataFromUserInput();
double dTotalHours = 0.0;
for (HourMin24 hm : ahm){
System.out.println("Time: " + hm.iHour + ":" + hm.iMin);
dTotalHours += hm.iHour + (hm.iMin / 60);
}
System.out.println("Average time (" + ahm.length + "): " + (dTotalHours / ahm.length));
}
private static final HourMin24[] getDataFromUserInput() {
Scanner in = new Scanner(System.in);
System.out.print("How many times? ");
int numOfTimes = in.nextInt();
ArrayList<HourMin24> al24 = new ArrayList<HourMin24>(numOfTimes);
while(numOfTimes < 0) {
System.out.println("What Time (military time): ");
System.out.print("Hour ");
int iHour = in.nextInt();
System.out.print("Minute ");
int iMin = in.nextInt();
al24.add(new HourMin24(iHour, iMin));
numOfTimes--;
}
return al24.toArray(new HourMin24[al24.size()]);
}
private static final HourMin24[] getTestData() {
System.out.println("TEST MODE ON");
return new HourMin24[] {
new HourMin24(13, 1),
new HourMin24(23, 19),
new HourMin24(0, 59),
new HourMin24(16, 16),
};
}
}
class HourMin24 {
public int iHour;
public int iMin;
public HourMin24(int i_hour, int i_min) {
iHour = i_hour;
iMin = i_min;
}
}
Output:
[C:\java_code\]java AverageTimeWTestingData
TEST MODE ON
Time: 13:1
Time: 23:19
Time: 0:59
Time: 16:16
Average time (4): 13.0