TreeMap collection issue - java

I am trying to create a program to keep track of College Teams and their sports records(Wins, Losses, years played). I want to use a Map(I opted for TreeMap) and a Set(I opted for TreeSet). I want to read the teams from a file and based on the input, update the database. For instance the line: 1975:UCLA:Brown would increment a win for UCLA, increment a loss of Brown and add the year 1975 to both teams.
The Key for the tree map will be the college names. the values is an object called TeamInfo
import java.util.TreeSet;
class TeamInfo {
int wins = 0;
int losses = 0;
TreeSet years;
TeamInfo(int wins, int losses, String year) {
// provide constructor code here
this.wins = wins;
this.losses = losses;
years = new TreeSet();
}
void incrementWins() {
wins++;
}
void incrementLosses() {
losses++;
}
void addYear(String aYear) {
// provide addYear code here
years.add(aYear);
}
public String toString() {
// provide toString() code here
return " Wins: " + wins + " Losses: " + losses + "\n" + "Years: " +
years.toString();
}
} // end TeamInfo
Ideally after reading from a file I should get the output:
Name: UCLA Wins:1 Losses:0
Name: Brown Wins:0 Losses: 1
My Problem comes when I have input like this:
1939:Villanova:Brown
1940:Brown:Villanova
1940:Brown:Villanova
I get output like this:
Name: Brown Wins: 2 Losses: 0
Years: [1940]
Name: Brown Wins: 0 Losses: 1
Years: [1939]
Name: Villanova Wins: 1 Losses: 1
Years: [1939, 1940]
Name: Villanova Wins: 0 Losses: 1
Years: [1940]
When the output should resemble:
Name:Brown Wins:2 Losses: 1
Name: Villanova Wins:1 Losses: 2
There are separate records for wins and losses for each team, when there should only be one record with both wins and losses. I've been staring at my code for hours and can't seem to see why it is doing that. Can anyone tell me what error I am committing and why this could be happening?
Thank You!
Here is my Main Class:
import java.util.TreeMap;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Iterator;
public class Records {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException {
File input = new File("C:\\Users\\Christian\\Desktop\\C code\\input4.txt");
Scanner test = new Scanner(input).useDelimiter("[:\n]");
TeamInfo tester;
String year ="";
String winner="";
String loser="";
TreeMap records = new TreeMap();
TeamInfo temp = new TeamInfo(0,0,"");
while(test.hasNext())
{
year = test.next();
winner = test.next();
loser = test.next();
/*search(test.next)
increment win
*/
if(!records.containsKey(winner))
{
TeamInfo firstRecord = new TeamInfo(0,0,"");
firstRecord.incrementWins();
firstRecord.addYear(year);
records.put(winner, firstRecord);
// System.out.println("First iteration of " + winner);
}
else if(records.containsKey(winner))
{
temp = (TeamInfo)records.get(winner);
temp.incrementWins();
temp.addYear(year);
records.replace(winner, temp);
// System.out.println("FOUND " + winner);
}
/*
search(test.next)*/
if(!records.containsKey(loser))
{
TeamInfo firstRecord = new TeamInfo(0,0,"");
firstRecord.incrementLosses();
firstRecord.addYear(year);
records.put(loser, firstRecord);
// System.out.println("First iteration of " + loser);
}
else if(records.containsKey(loser))
{
temp = (TeamInfo)records.get(loser);
temp.incrementLosses();
temp.addYear(year);
records.replace(loser, temp);
// System.out.println("FOUND " + loser);
}
/*increment loss
*/
}
while(!records.isEmpty())
{
temp = (TeamInfo)records.get(records.firstKey());
System.out.println("Name: " + records.firstKey().toString() + temp.toString());
records.remove(records.firstKey());
}
}
}

Related

Saving Inputs to txt. file in Java

I have been building program, where a. teacher is asked for information of 5. students and all the inputs should be saved after to a txt. file. Although my file is always created but is always empty...
Could someone please help me find my mistake ?
import java.util.Scanner;
import java.io.PrintWriter;
import java.io.IOException;
public class programming_project_1 {
public static void main(String[] args) throws IOException
{
int numbersOfLoops = 1;
Scanner scn = new Scanner(System.in);
while (true){
if (numbersOfLoops == 6){
break;
}
System.out.println("First Name: " );
String first_name = scn.next();
System.out.println("Last Name: " );
String last_name = scn.next();
System.out.println("Final Score: ");
int score = scn.nextInt();
numbersOfLoops++ ;
PrintWriter out = new PrintWriter("grades.txt");
System.out.println("First Name: " + first_name);
System.out.println("Last Name: " + last_name);
System.out.println("Final Score: " + score);
out.close();
}
}
}
You never write to out. Here:
System.out.println("First Name: " + first_name);
System.out.println("Last Name: " + last_name);
System.out.println("Final Score: " + score);
you probably meant out.println instead of System.out.println.
System.out is a PrintStream that writes to standard output. out, on the other hand, is a PrintWriter you declared and that writes to a file.
Also, you probably want to open the file before the loop and only close it afterwards, otherwise each iteration will overwrite the previous one.
Finally, a couple of asides:
that's a weird way of looping 5 times. You could use a for instead.
You should strive to respect java naming convention. Class names Start with an upper-case letter and use CamelCase, not snake_case. Same for variables, but they start with lower-case letters.
To sum it up:
import java.util.Scanner;
import java.io.PrintWriter;
import java.io.IOException;
public class ProgrammingProject1 {
public static void main(String[] args) throws IOException
{
Scanner scn = new Scanner(System.in);
PrintWriter out = new PrintWriter("grades.txt");
for (int i = 0; i < 5; i++) {
System.out.println("First Name: " );
String firstName = scn.next();
System.out.println("Last Name: " );
String lastName = scn.next();
System.out.println("Final Score: ");
int score = scn.nextInt();
out.println("First Name: " + firstName);
out.println("Last Name: " + lastName);
out.println("Final Score: " + score);
}
out.close();
}
}

How do i get my input value from one method to print in another method, ive looked all over the site and nothings worked

I'm trying to get my input from int stuScore=keyboard.nextInt(); in the populateTestScores method into the printStudentReport method without using a class. I have an attachment of how its supposed to look in a link at the end.
Can anyone help me out?
public static void populateTestScores(String[]names,int[][]scores)
{
for(int stuNames = 0; stuNames < names.length; stuNames++)
{
System.out.println();
System.out.println("Entering scores for " + names[stuNames] +":" );
for(int testNum=0; testNum<scores[0].length; testNum++)
{
System.out.print("Enter score for test #" + (testNum+1) + ":" );
int stuScore=keyboard.nextInt();
}
System.out.println();
}
}
public static void printStudentReport(String[]names,int[][]scores)
{
System.out.println("Student Report");
System.out.println();
for(int stuNames = 0; stuNames < names.length; stuNames++)
{
System.out.println("Scores for " + names[stuNames] +":" );
for(int testNum=0; testNum<scores[0].length; testNum++)
{
System.out.println("Test " + (testNum+1) + ":" + scores[stuNames][testNum] );
}
System.out.println();
}
}
this is what it needs to print http://jonlebeau.com/courses/244/StuTest.Output.txt
This should be a comment instead of an answer but i dont have the reputation for that.
you are providing the populate method with a scores array. This can work when you have an enclosing class that keeps that array as a field, which the print method can access.
As i understand, you don't want to use a class that encapsulates these 2 methods, so i suggest you to initialize the scores inside the populate method and make the populate method return the scores . the response can then be used to pass to the printer method when running the
hope this helps, Feel free to ask!
You can call the method
printStudentReport(String[]names,int[][]scores)
like
printStudentReport(String[]names,int[][]scores, int stuScore)
from populateTestScores method.
But according to your sample output the printStudentReport method should execute after populateTestScores has executed (for the flow of the output)
So I suggest creating a data structure (array, list etc) to store all the stuScores (in populateTestScores as you are already looping through it) and sent the data structure to printStudentReport like and print it with the for loop again.
printStudentReport(String[]names,int[][]scores, data Structure type stuScore)
I also suggest you consider complexity in theses cases. See if you can minimize the for loop into one.
Method to collect data using scanner:
private static void populateTestScores(){
Scanner scan = new Scanner(System.in);
System.out.println("Enter number of tests:");
noOfTests = scan.nextInt();
System.out.println("Enter number of students:");
noOfStudents = scan.nextInt();
List<String> names = new ArrayList<String>();
for (int i = 0; i < noOfStudents; i++) {
System.out.println("Enter student "+ (i + 1) +" name:");
names.add(scan.next());
}
for (String name: names) {
System.out.println("Entering scores for " + name + ":");
List<Integer> marks = new ArrayList<Integer>();
for (int i = 0; i < noOfTests; i++) {
System.out.println("Enter score for test #" + (i + 1) +":");
marks.add(scan.nextInt());
}
studentMarks.put(name, marks);
}
}
Method to Print Student Report:
private static void printStudentReport(){
System.out.println("STUDENT REPORT");
System.out.println(noOfStudents + " student(s) took " + noOfTests + " test(s).");
for (String name : studentMarks.keySet()) {
System.out.println("Entering scores for " + name);
List<Integer> marks = studentMarks.get(name);
int sum = 0;
for (int i = 0; i < noOfTests; i++) {
System.out.println("\tEnter score for test #" + (i + 1) + " : " + marks.get(i));
sum += marks.get(i);
}
System.out.println("\tAverage for " + name + " : " + sum / noOfTests);
}
}
You can go with the below solution to achieve this output.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class School {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter number of student(s) : ");
int studentCount = input.nextInt();
System.out.print("Enter test count : ");
int testCount = input.nextInt();
System.out.println("\n" + studentCount + " student(s) took " + testCount + " test(s)\n");
List<Student> studentList = new ArrayList<>();
for (int i = 1; i <= studentCount; i++) {
System.out.print("Enter student " + i + " name: ");
Scanner nameInput = new Scanner(System.in);
String studentName = nameInput.nextLine();
Student student = new Student();
student.setName(studentName);
studentList.add(student);
}
System.out.println("\n");
for (Student student : studentList) {
System.out.println("Entering scores for " + student.getName() + ":");
for (int i = 1; i <= testCount; i++) {
System.out.print("\tEnter score for test #" + i + ": ");
Scanner scoreInput = new Scanner(System.in);
int score = scoreInput.nextInt();
student.getTest().add(score);
}
}
System.out.println("\nSTUDENT REPORT");
for (Student student : studentList) {
System.out.println("Scores for " + student.getName() + ":");
int total = 0;
for (int i = 1; i <= student.getTest().size(); i++) {
int temp = i - 1;
total = total + student.getTest().get(temp);
System.out.println("\tTest #" + i + ": " + student.getTest().get(temp));
}
double temp = (double) total / student.getTest().size();
double avg = (double) Math.round(temp * 100) / 100;
System.out.println("\tAverage for " + student.getName() + ": " + avg);
}
}
}
class Student {
private String name;
private List<Integer> test = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Integer> getTest() {
return test;
}
public void setTest(List<Integer> test) {
this.test = test;
}
}
and below is the output :
Enter number of student(s) : 5
Enter test count : 2
5 student(s) took 2 test(s)
Enter student 1 name: A
Enter student 2 name: B
Enter student 3 name: C
Enter student 4 name: D
Enter student 5 name: E
Entering scores for A:
Enter score for test #1: 12
Enter score for test #2: 11
Entering scores for B:
Enter score for test #1: 14
Enter score for test #2: 15
Entering scores for C:
Enter score for test #1: 12
Enter score for test #2: 13
Entering scores for D:
Enter score for test #1: 14
Enter score for test #2: 15
Entering scores for E:
Enter score for test #1: 11
Enter score for test #2: 12
STUDENT REPORT
Scores for A:
Test #1: 12
Test #2: 11
Average for A: 11.5
Scores for B:
Test #1: 14
Test #2: 15
Average for B: 14.5
Scores for C:
Test #1: 12
Test #2: 13
Average for C: 12.5
Scores for D:
Test #1: 14
Test #2: 15
Average for D: 14.5
Scores for E:
Test #1: 11
Test #2: 12
Average for E: 11.5

Text based survival Game

So I just whipped up this quick little demo game in like 30 minutes and I was wondering 2 things:
How could I organize my code more?
Would you be willing to play a game like this?
I know that I could use classes but I'm a bit inexperienced them. I'm confused on how to get variables from specific classes. Would I need to import them into the main method class?
import java.util.Scanner;
public class mainGame
{
public static Scanner kboard = new Scanner(System.in);
public static boolean loop = true;
public static int treesInArea = 0;
public static int day = 0;
public static int wood = 0;
public static int woodCollected = 0;
public static int woodLevel = 0;
public static void main(String[] args)
{
System.out.println("__________________________________");
System.out.println(" Welcome to seul...Lets begin ");
System.out.println(" You woke up in the middle of ");
System.out.println(" a forest. Use the command walk ");
System.out.println(" in order to walk into a new area ");
System.out.println("__________________________________\n");
while(loop == true)
{
String choice = kboard.nextLine();
if(choice.equalsIgnoreCase("walk"))
{
treesInArea = (int)(Math.random() * 20);
System.out.println("__________________________________");
System.out.println("The number of trees in this area is");
System.out.println(treesInArea + " trees");
System.out.println("__________________________________\n");
day++;
System.out.println(" It is day " + day + " ");
System.out.println("__________________________________\n");
System.out.println(" Current usuable commands are : ");
System.out.println(" - Chop tree\n");
} else
if(choice.equalsIgnoreCase("choptree") || choice.equalsIgnoreCase("chop tree"))
{
if(treesInArea < 1)
{
System.out.println("There are no trees in this area.");
} else
{
woodCollected = (int)(Math.random() * 10);
treesInArea --;
wood += woodCollected;
woodLevel += (int)(Math.random() * 2);
System.out.println("__________________________________");
System.out.println(" You collected " + woodCollected + " wood");
System.out.println(" Your total wood = " + wood);
System.out.println(" Your total woodcutting level = " + woodLevel);
System.out.println("__________________________________\n");
}
}
}
}
}
You could improve your code in 4 main ways:
1 • Your code-indentation is not great, it should be a 4 space(or just press tab) indent after class name, loops, if statements etc. Example:
private methodName() {
for(int i = 0; i < 10; i++;) {
//do something
}
}
2 • It is easier to read your code when braces are right after methods/loops, and it takes less space, such as(5 lines of neat code):
if (condition = true) {
//do something
} else {
//do something else
}
Rather than(7 lines of messy code):
if (condition = true)
{
//do something
} else
{
//do something else
}
because when you have long if-else blocks, or long loops, it can become hard to read.
3 • You do not need to add spaces after a line, this does nothing. So this:
System.out.println(" It is day " + day + " ");
Can become this:
System.out.println(" It is day " + day);
4 • Lastly, the best way to organize code is by "dividing and conquering". This means make methods even if they're very short, to prevent repeat-code and save time. For example, you printed this line: System.out.println("__________________________________"); 7 times in your program. If you make a method like the one below, you can save time and space, by avoiding repeat-code, and simply call the method using printDivider(); wherever you used this line:
private static void printDivider() {
System.out.println("__________________________________");
}
Yes, I would play your game(in fact i did play your game), but you could improve it, by adding more possibilities, or different 'paths' to go down, ending in different results.

Number instead of the candidates name change

import uulib.GUI;
import java.util.Scanner;
import uulib.Num;
/**
* Write a description of class votes1 here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class votes1
{
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
String[]name=new String[6]; //candidates name
int[]vote=new int[6]; //candidates vote
int total_votes=0; //total votes
double[] percentage = new double[6]; //candidates percentage
int threshold=GUI.getInt("Enter threshold");
for(int i=0;i<name.length;i++){
System.out.println("Enter candidates last name");
name[i]=in.next();
System.out.println("Please enter the total votes for " + name[i]);
vote[i]=in.nextInt();
total_votes+=vote[i];
}
for(int i=0;i<vote.length;i++){
percentage[i]=(double) vote[i]/(double)total_votes*100.0;
}
int bel_threshold=vote[0];
int winner=vote[0];
for(int i=1;i<vote.length;i++)
{
if(vote[i]>winner)
{
winner=vote[i];
}
while(vote[i]<threshold){
bel_threshold=vote[i];
}
}
System.out.println("Candidate"+"\t"+"Votes"+"\t"+"%");
for(int i=0;i<vote.length;i++)
{
System.out.println(name[i]+"\t" + " \t"+vote[i]+"\t"+ Num.format(percentage[i],1));
System.out.println();
}
System.out.println("Total votes"+"\t" +total_votes);
System.out.println("Threshold" +"\t"+ threshold);
System.out.println("Winner: " + "\t" + winner);
System.out.println("Below threshold"+"\t" + " \t" + bel_threshold);
}
}
For the winner and below_threshold it shows the number of the low and high votes, i want to display the names of the candidates. How can i print the winner and below_threshold candidates name instead of their vote?
Keep the index in winner (not the votes). Like
int winner = 0;
for(int i=1;i<vote.length;i++)
{
if(vote[i]>vote[winner]){
winner = i;
}
}
Then print the winner like,
System.out.println("Winner: " + name[winner]);
String[ ] name:
+----+----+----+----+
| 0 | 1 | 2 | 3 | <--Array index
+----+----+----+----+
|Cdd1|Cdd2|Cdd3|Cdd4| <--Names of Candidates (String array)
+----+----+----+----+
int[ ] vote:
+----+----+----+----+
| 0 | 1 | 2 | 3 | <--Array index
+----+----+----+----+
|120 |550 |330 |220 | <--Votes of Candidates (int array)
+----+----+----+----+
This is what we call parallel arrays.
Meaning that same index corresponds to the same person.
Since the array index for name[] and vote[] matches,
the index of the highest vote will also be the index of the name (candidate)
with the highest vote.
Since you used winner to hold the index of the highest vote, just use winner again as the index to print out the name with the highest vote.
To print winner's name, simply do this:
System.out.println("Winner: " + "\t" + name[winner]);
It is easy to print out the names of the candidates below threshold. I think you don't need to store the candidates names right? You can just call a very simple method to do that:
public static void main(String[] args){
//Candidates below threshold
print_Below_Threshold(threshold, name, votes);
}
public static void print_Below_Threshold(int threshold, String[] name, int[] votes){
for(int x=0; x<name.legnth; x++)
if(votes[x] < threshold)
System.out.print(name[x] + " ");
}
If you are not allowed to use method for any reason, just write the 3 lines of codes directly in your main where you need to print the candidates below threshold.

method getHomeworkSum() returns lastest homework value, not the sum

There are two classes. class 1 has the methods. class 2 calls the methods. I will show you the part of class 1 that i need help on, but will include the entirety of class 2 since it is much shorter than class 2.
class 1
public void setHomeworkSum() {
homeworkSum =+ homeworkScore;
}
public int getHomeworkSum() {
return homeworkSum;
}
class 2
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class CourseGrade {
public static void main(String[] args) {
Student myStudent = new Student();
myStudent.openFile();
myStudent.setNumberOfStudents();
System.out.format("%-10s %25s %15s %10s", "Name", "Assignment score", "Test score", "Grade\n");
System.out.println();
for(int i = 1; i <= myStudent.getNumberOfStudents(); i++){
myStudent.setDefault();
myStudent.setFirstName();
myStudent.setLastName();
myStudent.setHomeworkScore();
myStudent.setTestScore();
myStudent.setHomeworkScore();
myStudent.setTestScore();
myStudent.computeGrade();
System.out.format("%-19s %1s %21s %13s", myStudent.getFirstName() + " " + myStudent.getLastName(), myStudent.getHomeworkScore(), myStudent.getTestScore(), myStudent.getGrade() +"\n");
myStudent.setPassFail();
myStudent.setHomeworkSum();
}
System.out.println();
System.out.println("No. of students passed: " + myStudent.getPass());
System.out.println();
System.out.println("No. of students failed: " + myStudent.getFail());
System.out.println();
System.out.println("sum: " + myStudent.getHomeworkSum());
}
}
basically, the problem i'm having is it doesn't return the sum of all the homeworkscores, but instead returns the latest individual homeworkscore that was read.
Output:
Name Assignment score Test score Grade
Anthony Hopkins 854 284 G
John Smith 730 214 A
Pan Mei 730 267 A
Rafael Vega 801 236 A
No. of students passed: 4
No. of students failed: 0
mean 801
(the top part didn't convert correctly, but you get the idea.)
Change to
homeworkSum += homeworkScore;
You had
homeworkSum =+ homeworkScore;
which, if you put some space, basically is
homeworkSum = +homeworkScore;
so you are always assigning the last value to the variable.

Categories

Resources