I am currently trying to work on a program that uses student ID's and GPA's (taken from a txt file) and uses these to do numerous other things like categorize the students into 1 of 8 categories based on GPA ranges, make a histogram of the students in each group, and also rank the students by GPA. The first thing I need to do however is transfer the student ID's and GPA's into two separate arrays.
I know the syntax for creating an array is as follows:
elementType[] arrayRefVar = new elementType[arraySize]
However, I still don't know how to pass the data that is read from the file into two separate arrays. The code I have to read the data from the txt file is as follows:
public static void main(String[] args) throws Exception // files requires exception handling
{
String snum;
double gpa;
Scanner gpadata = new Scanner(new File("studentdata.txt"));
while (gpadata.hasNext()) // loop until you reach the end of the file
{
snum = gpadata.next(); // reads the student's id number
gpa = gpadata.nextDouble(); // read the student's gpa
System.out.println(snum + "\t" + gpa); // display the line from the file in the Output window
}
}
So my question is: how do I pass this information into two separate arrays? I apologize if my question is hard to understand, I am extremely new to programming. I have been stumped on this program for a long time now, and any help would be extremely appreciated! Thank you.
You can create two arrays before the while loop, and then add each element inside the loop to each array. But there is one problem with this approach: we don't know the number of values, thus we cannot create a fixed-sized array for this. I suggest to use ArrayList instead, which can grow as needed. Something like this:
public static void main(String[] args) throws FileNotFoundException {
Scanner gpadata = new Scanner(new File("studentdata.txt"));
List<String> IDs = new ArrayList<>();
List<Double> GPAs = new ArrayList<>();
while (gpadata.hasNext()) // loop until you reach the end of the file
{
String snum = gpadata.next(); // reads the student's id number
double gpa = gpadata.nextDouble(); // read the student's gpa
IDs.add(snum);
GPAs.add(gpa);
System.out.println(snum + "\t" + gpa); // display the line from the file in the Output window
}
// Use IDs and GPAs Lists for other calculations
}
A more better approach to use a Map to "pair" a GPA to a Student ID.
Edit:
After you clarified that the max record number never be more than 1000, I modified my solution to use arrays instead of Lists. I didn't change the variable names so you can compare the solutions easily.
public static void main(String[] args) throws FileNotFoundException {
Scanner gpadata = new Scanner(new File("studentdata.txt"));
String[] IDs = new String[1000];
double[] GPAs = new double[1000];
int counter = 0;
while (gpadata.hasNext()) // loop until you reach the end of the file
{
String snum = gpadata.next(); // reads the student's id number
double gpa = gpadata.nextDouble(); // read the student's gpa
IDs[counter] = snum;
GPAs[counter] = gpa;
System.out.println(snum + "\t" + gpa); // display the line from the file in the Output window
counter++;
}
// Use IDs and GPAs Lists for other calculations
}
Note that we need a counter (aka. index) variable to address the array slots.
Related
The user should be able to input data of 5 customers with balances. However this piece of code only works for 1. I initially thought of using a for OR a while loop but I think they will create the display message 5 times.
import java.util.Scanner;
public class Assignment {
public static void main (String [] args) {
Scanner scan = new Scanner (System.in);
Customer c [] = new Customer [5];
Customer hold;
String name; int count = 0;
double totalBalance = 0.0;
System.out.println("For 5 customers enter the name and in the next line the balance"); // displays the message to user
String name = scan.next();
double balance = scan.nextDouble();
c [count++]= new Customer(name,balance);
System.out.println("Search for all customers who have more than $100");
for (int i=0; i<count ; i++){
if (c[i].getBalance()>100)
System.out.println(c[i].getName());
totalBalance += balance;
averageBalance = totalBalance/5;
System.out.println("The average balance is: "+averageBalance);
}
}
System.out.println("For 5 customers enter the name and in the next line the balance"); // displays the message to user
for(int i=0; i<5; i++){
String name = scan.next();
double balance = scan.nextDouble();
c [count++]= new Customer(name,balance);
}
So, in the above code the display message prints 5 times but every time it will be for different customers. For e.g.
Enter 1 customer name and balance
John
20.0
Enter 2 customer name and balance
Jim
10.0
and so on.
I hope this helps. If you ask me you should be using java.util.ArrayList or java.util.LinkedList. These classes come with many features out of the box and you need not code much as in the case of arrays.
You are asking is not a coding problem but just a matter of design.
For what you are doing as per design you can follow below process or similar.
Enter comma separated user names in single line.
Read the line and split the names, now you have x customers detail like name read in a single shot.
Now you have names, repeat 1-2 above for every type of detail just need to be entered comma separated. Try to take one type of detail at a time, i.e. one, line one detail like salary of emp or department.
for pseudo code:
private String[] getDetails(BuffferReader reader){
// read a line at a time, using readline function
// using readed line/console input, split it on comma using split() function and return array of values.
}
I am trying to generate an arraylist in java by first inputting the default size desired of the said arraylist. Then I want to get the user to input the string to fill the arraylist. I have made one that almost works. The only problem is that for some reason I get a default value at the start.
For example, if I set the list length to 3 the list returned is: [,example,value,here]. I understand a value of 3 means 4 values in a list but I feel like that just doesn't look too nice. The problem I think lies in the way I set the size of the list but I don't see any other way.
When I set the list value manually in the for loop I don't get this problem. It only happens when I want the user to input the length. Where is the small error?
import java.util.*;
public class ListsPractice {
public static void main(String[] args) {
Scanner userin = new Scanner(System.in);
System.out.println("Enter length of desired list: ");
int lenlist = userin.nextInt();
ArrayList list1 = new ArrayList();
for(int counter = 0; counter <= lenlist; counter++) {
System.out.println("Enter an element: ");
String value=userin.nextLine();
list1.add(value);
}
System.out.println("the result is: "+list1.subList(1, lenlist+1));
}
}
I have to make a Java Program, where a user type in the total numbers of students, so I made this code:
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int numReaders = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of magazin readers:");
numReaders = scan.nextInt();
Now, after adding the total number of students, we should add their names into an array:
//Creating an array of names, where the length is the total number entered by the user
String[] nameStr = new String[numReaders];
int[] ages = new int[numReaders];
for(int i=0; i<numReaders; i++)
{
Scanner n = new Scanner(System.in);
System.out.println("Enter the name of reader: "+i);
nameStr[i] = n.next();
}
After that, we should add correspondingly the age of each name, so I made this portion of code:
for(int i=0; i<numReaders; i++)
{
Scanner a = new Scanner(System.in);
System.out.println("Enter the age of reader: "+i);
ages[i] = a.nextInt();
}
//Display the results
System.out.println("Number of readers is: "+numReaders);
for (int i=0; i<numReaders; i++)
{
System.out.println("The name of reader "+i+" is "+nameStr[i]+ " and his age is "+ages[i]);
}
After making this code, I tested it using Ideone and Command Prompt and it works properly:
Now, I need to call method according to selection of the user:
if he typed 'a' a method should be called to specify the name and the age of the oldest student.
If he typed 'b' a method called to see how many students have an age specified by the user and If he typed 'c', a function called to calculate the average age of them all.
I am new to methods so I don't know how to add arrays into methods and make statements.
Here is the full code:
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int numReaders = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of magazin readers:");
numReaders = scan.nextInt();
//Creating an array of names, where the length is the total number entered by the user
String[] nameStr = new String[numReaders];
int[] ages = new int[numReaders];
for(int i=0; i<numReaders; i++)
{
Scanner n = new Scanner(System.in);
System.out.println("Enter the name of reader: "+i);
nameStr[i] = n.next();
}
for(int i=0; i<numReaders; i++)
{
Scanner a = new Scanner(System.in);
System.out.println("Enter the age of reader: "+i);
ages[i] = a.nextInt();
}
//Display the results
System.out.println("Number of readers is: "+numReaders);
for (int i=0; i<numReaders; i++)
{
System.out.println("The name of reader "+i+" is "+nameStr[i]+ " and his age is "+ages[i]);
}
//Choosing a statistic
//if a:
System.out.println("Please choose a, b or C:");
Scanner stat = new Scanner(System.in);
char X;
X = stat.next().charAt(0);
if(X=='a')
System.out.println(X+X);
else if(X=='b')
//System.out.println(X);
//Scanner newAge = new Scanner(System.in);
//int ageToSearchFor = newAge.nextInt();
//maxAge(ageToSearchFor);
else
System.out.println(X);
}
}
Right, so to start with your user enters an input, for example 'a', so let's go with this:
Firstly, you need to create the method where the name of the oldest student is displayed, so let's call it 'getOldestStudent' - when naming methods this is the typical naming convention, starting lowercase and then moving to uppercase for each new word - try and make them as intuitive as possible.
When making the method signature, you need to give it its visibility and also what it is going to return. In this case, as you are only using one class, we will give it private, so it is only visible by this class.
Now we need to return 2 things, so we can either put these into a string or put them into an array, which is what I would recommend, so we are going to return an array. However, you want to input an array to search through, so this goes in tbe brackets as parameters (or arguments). Therefore our method signature is the following:
private String[] getOldestStudent(String[] students, int[] ages)
Then inside this method, you can simply do the code you need to find the oldest student, add their name and age to the array and then return this.
Need anymore help just drop a comment.
On a side note, you would have been better off creating a 'Student' object and then giving this object a 'name' property and an 'age' property and then simply making an array of students and getters and setters (or accessors and mutators) for these properties.
James Lloyd's covers your question pretty well, I thought I might add some input as I think you are struggling with some principles.
At first, I would do as James advised and create a class Student that stores the values for each person.
public class Student {
public String name;
public int age;
// Constructors allow you to create a new Object and set some variables
// when you create it.
public Student (String name) {
this.name = name;
}
}
I used public to avoid getters and setters for this explanation, but I'd use private most had I to write it by myself.
Anyways, that way you only have to use one instead of two arrays (and name and age are connected with each other, e.g., you know the age of a student you know the name of, whereas with two different arrays it could happen that you don't know if nameArray[0] belongs to ageArray[0].
So you have an array Student[] students = new Student[numReaders]; and you can set each Student after reading the input, i.e., after reading the name you call students[i] = new Student(name); If you want to set the age of a Student afterwards you can do so by using student[i].age = age.
Now that we have filled our array, we can advance to your actual question.
char method;
method = stat.next().charAt(0);
// I think switch is a little easier to read for such cases
switch(method) {
case 'a': Student oldest = getOldestStudent(students);
if (oldest != null)
System.out.println(oldest.name);
break;
case 'b': //another method
break;
default: // equals to else as if none of the other cases was fulfilled
break;
}
Now you can write your own method for each scenario you have to cover.
public Student getOldestStudent(Student[] students) {
// at first we check some cases that do not require further checks
if (students.length == 0) {
System.out.println("No students have been specified");
return null; // this might lead to a NullPointerException so check the return Object whether it is null before doing anything with it
} else if (students.length == 1)
return students[0];
// no we have to see which students if the oldest in the regular case
// the first student will be used for comparison
Student oldestStudent = students[0];
for (int i = 1; i < students.length; i++) {
// see if our current student is older
if (oldestStudent.age < students[i].age)
oldestStudent = students[i];
}
return oldestStudent;
}
This way you can easily access the Students name afterwards (see above in the switch). You can build all your methods like this by passing the array to the methods and iterating through it. Depending on whether you want to return one or more Students (as it might vary between the different methods) you have to change the return type from Student to Student[].
I have two different programs, one which contains a method "addGrade" designed to add a new grade to a 2D array (gradeTable). One array of the 2D array is the category each grade should be in, and the second element is the grades for each category. Here is that program:
public class GradeBook {
private String name;
private char[] categoryCodes;
private String[] categories;
private double[] categoryWeights;
private double[][] gradeTable;
public GradeBook(String nameIn, char[] categoryCodesIn,
String[] categoriesIn, double[] categoryWeightsIn) {
name = nameIn;
categoryCodes = categoryCodesIn;
categories = categoriesIn;
categoryWeights = categoryWeightsIn;
gradeTable = new double[5][0];
}
public boolean addGrade(String newGradeIn) {
char row = newGradeIn.charAt(0);
int grade = Integer.parseInt(newGradeIn.substring(1));
double[] oldArr = gradeTable[row];
double[] newArr = Arrays.copyOf(oldArr, oldArr.length + 1);
newArr[newArr.length - 1] = grade;
gradeTable[row] = newArr;
return row != 0;
}
The second program reads in a file as a command argument. The bolded text represents the grades being read in. The letter stands for that category each grade should be in, and the number is the actual grade. The file is
Student1
5
a Activities 0.05
q Quizzes 0.10
p Projects 0.25
e Exams 0.30
f Final 0.30
**a100 a95 a100 a100 a100
q90 q80 q100 q80 q80 r90
p100 p95 p100 p85 p100
e77.5 e88
f92**
In the second program, I'm trying to loop through each grade in the file and call the addGrade method on it so it will be added to the 2D array. I'm unsure of how to call the method for each individual grade. Also, I'm pretty sure my addGrade method isn't right. Any help would be appreciated. This is the second program:
public class GradeBookApp {
String fileName = "";
String name = "";
char[] categoryCodes = new char[5];
String[] categories = new String[5];
double[] categoryWeights = new double[5];
double[][] gradeTable;
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
System.out.println("Reading file \"" + args[i] + "\"."
+ "\n\tCreating GradeBook object."
+ "\n\tAdding grades to GradeBook object."
+ "\nProcessing of file complete.");
fileName = args[i];
Scanner scanFile = new Scanner(new File(fileName));
name = scanFile.nextLine();
int catCodes = Integer.parseInt(scanFile.nextLine());
for (i = 0; i < catCodes; i++) {
String[] all = scanFile.nextLine().split(" ");
if(all.length == 3 && all[0].length() == 1 && all[2].matches("(\\d+\\.\\d+)")){
categoryCodes[i] = all[0].charAt(0);
categories[i] = all[1];
categoryWeights[i] = Double.parseDouble(all[2]);
}
}
GradeBook myGB = new GradeBook (name, categoryCodes,
categories, categoryWeights);
You'd be better off with having each list of grades as an ArrayList<Double> rather than a double[]. It's very hard work on the JVM (and on the programmer!) having to copy the whole array each time so that you can increase its length and add a new one. If you use an ArrayList<Double> gradeList, then you can just
gradeList.add(grade);
without needing to do all the copying.
I would also consider having the larger structure as a Map rather than an array. So rather than having a two-dimensional array, you could have a HashMap<Character,List<Double>> that maps the row onto the list of grades for that row. That avoids having to convert between characters and doubles, which you're currently (implicitly) doing.
Finally, the addGrade() method ought to take a char and a double (a row and a new grade), rather than a String: you're making a lot of work for yourself with having to process inappropriate data structures.
Once you've done this, calling addGrade for each item should be fairly easy. Once you've extracted a String representing a particular grade (say, String gr = "e77.5") then you can add to the list inside your HashMap gradeMap like this:
char row = gr.charAt(0);
double grade = Double.parseDouble(gr.substring(1));
gradeMap.get(row).add(grade);
I think you'll need to supply more info if you need more help than that.
You stated that you need to read from a file, but none of your code is actually reading from a file. This should be your first step. Try looking at BufferedReader documentation as well as numerous posts on this site regarding proper methods to perform file IO operations.
I'm assuming your storing your grades in the 2D gradeTable array like: {Category, grade}. You will need to read each row in your file(BufferedReader has methods for this), parse the string (Look at the String documentation, specifically split or substring/indexOf methods) into category and grade, and then populate your array.
Look into using more dynamic data structures, such as ArrayList. This will allow you to expand the size as you add more grades, as well as not having to copy your array into a new array every time the size expands.
I'm working on a program that acts as a type of book store inventory. The program reads in a list of information from a text file that looks like this:
1234567 31.67 0
1234444 98.50 4
1235555 27.89 2
1235566 102.39 6
1240000 75.65 4
1247761 19.95 12
1248898 155.91 0
1356114 6.95 17
1698304 45.95 3
281982X 31.90 5
The first number represents the ISBN number and is the type String, the second number is the price and is type double, and the final number is the number of copies in stock and is an int.
The program is supposed to read in this information, storing it into an array (more steps follow, but this is the first thing I'm having trouble with).
The code I have so far looks like this:
import java.util.Scanner;
import java.io.*;
public class Store {
public static void main(String[] args) {
String[] books = new String[15];
String product;
readInventory();
}
public static void readInventory() {
java.io.File file = new java.io.File("../instr/prog4.dat");
Scanner fin = new Scanner(file);
String isbn;
double price;
int copies;
String[] books = new String[14];
while (fin.hasNext()) {
isbn = fin.next();
price = fin.nextDouble();
copies = fin.nextInt();
}
}
}
I'm having trouble figuring out how to store these three different pieces of information into a single line (for each item like is depicted in the file) in a single dimensional array.
One thought I had was to created something like this,
String product = (isbn + price + copies);
And then try to add this to the array like,
String[] books = product;
But as I'm sure you can probably sport, this didn't work. Any suggestions would be greatly appreciated. I'm still really new to this and it's been a while since I've worked with arrays.
I'm having trouble figuring out how to store these three different pieces
of information into a single line
How about using nextLine()
String[] books = new String[14];
int index = 0;
while (fin.hasNextLine()) {
books[index] = fin.nextLine();
index++;
}
From there you can pull out each String and split it around the spaces
String[] parts = books[0].split(" ");
Now you can cast each part to its respective type
String isbn = parts[0];
double price = Double.parseDouble(parts[1]);
int numberInStock = Integer.parseInt(parts[2]);
Beware this is a long way around and will cause problems if your file contains variable amounts of books. Also, to do this for all books will require some loops.