How to connect two class modules together in Java? - java

I have a program that contains five .txt files. These files are read in and put into different arrays. One is an array of names. The other four are arrays with test scores.
Currently, the program does create the arrays correctly. Next the program is to calculate and display the average for each test (this works fine). Then the program prompts the user for a name. If a name is found a new menu will prompt the user to select which test they want the data on. (This works fine).
The problem: I have the main program class and another GradeBook class (does calculations) on another page. How do I connect the two pages together?
For example: If the studentName is 'Andrew' and it is found in studentNameArray, and I select 1 for which test score I want to see (scoreOneArray), say the number 88. My program finds 'Andrew' and '88'. What it does not do is send 'Andrew' and '88' to GradeBook to have the data compute test percentage (88/100) and find the corresponding letter grade (in this case 'B'). Lastly, then print students name, test score (88%), and the letter grade.
Program (main):
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
double test1Calculation;
double test2Calculation;
double test3Calculation;
double test4Calculation;
int i, j, k, l;
int testOneSum = 0;
int testTwoSum = 0;
int testThreeSum = 0;
int testFourSum = 0;
int checker = 0;
int index=0;
String choice;
Scanner students = new Scanner(new File("names.txt"));
Scanner TestOne = new Scanner(new File("testOne.txt"));
Scanner TestTwo = new Scanner(new File("testTwo.txt"));
Scanner TestThree = new Scanner(new File("testThree.txt"));
Scanner TestFour = new Scanner(new File("testFour.txt"));
String token1 = "";
List<String> studentName = new ArrayList<>();
while (students.hasNext()) {
// find next line
token1 = students.next();
studentName.add(token1);
}
String[] studentNameArray = studentName.toArray(new String[0]);
List<Integer> scoreOne = new ArrayList<>();
// while loop
while (TestOne.hasNext()) {
// find next line
Integer token2 = TestOne.nextInt();
scoreOne.add(token2);
}
Integer[] scoreOneArray = scoreOne.toArray(new Integer[0]);
List<Integer> scoreTwo = new ArrayList<>();
// while loop
while (TestTwo.hasNext()) {
// find next line
Integer token3 = TestTwo.nextInt();
scoreTwo.add(token3);
}
Integer[] scoreTwoArray = scoreTwo.toArray(new Integer[0]);
List<Integer> scoreThree = new ArrayList<>();
// while loop
while (TestThree.hasNext()) {
// find next line
Integer token4 = TestThree.nextInt();
scoreThree.add(token4);
}
Integer[] scoreThreeArray = scoreThree.toArray(new Integer[0]);
List<Integer> scoreFour = new ArrayList<>();
// while loop
while (TestFour.hasNext()) {
// find next line
Integer token5 = TestFour.nextInt();
scoreFour.add(token5);
}
Integer[] scoreFourArray = scoreFour.toArray(new Integer[0]);
for (i = 0; i < scoreOneArray.length; i++)
testOneSum += scoreOneArray[i];
test1Calculation = (double) testOneSum / 5;
for (j = 0; j < scoreTwoArray.length; j++)
testTwoSum += scoreTwoArray[j];
test2Calculation = (double) testTwoSum / 5;
for (k = 0; k < scoreThreeArray.length; k++)
testThreeSum += scoreThreeArray[k];
test3Calculation = (double) testThreeSum / 5;
for (l = 0; l < scoreFourArray.length; l++)
testFourSum += scoreFourArray[l];
test4Calculation = (double) testFourSum / 5;
System.out.println("The average for test one is: " + test1Calculation);
System.out.println("The average for test two is: " + test2Calculation);
System.out.println("The average for test three is: " + test3Calculation);
System.out.println("The average for test four is: " + test4Calculation);
Scanner studentSearch = new Scanner(System.in);
System.out.println("Enter student name : ");
String foundStudent = studentSearch.nextLine();
boolean found = Arrays.stream(studentNameArray).anyMatch(t -> t.equals(foundStudent));
if (found) {
index++;
System.out.println(foundStudent + " is found.");
//menu loop
do {
//displayed user options
System.out.println("1. To find score for first test");
System.out.println("2. To find score for second test");
System.out.println("3. To find score for third test");
System.out.println("4. To find score for fourth test");
//menu choices
Scanner keyboard = new Scanner(System.in);
System.out.print("\nEnter your choice: ");
choice = keyboard.next();
if (choice.equals("1")) {
int score= scoreOneArray[index];
System.out.println(score);
checker = -1;
} else if (choice.equals("2")) {
int score= scoreTwoArray[index];
System.out.println(score);
checker = -1;
} else if (choice.equals("3")) {
int score= scoreThreeArray[index];
System.out.println(score);
checker = -1;
} else if (choice.equals("4")) {
int score= scoreFourArray[index];
System.out.println(score);
checker = -1;
} else {
//Error message
System.out.println("invalid choice");
}
}
while (checker != -1);
} // End of Menu Method
else {
System.out.println(foundStudent + " is not found.");}
students.close();
TestOne.close();
TestTwo.close();
TestThree.close();
TestFour.close();
}
}
Calculations(GradeBook):
import java.util.ArrayList;
public class GradeBook {
private char[] letterGrade = {'A', 'B', 'C', 'D', 'F'};
private ArrayList<String> names = new ArrayList<>();
private double [][] scores = new double[5][4];
public GradeBook(ArrayList<String> studentNames, double[][] studentScores){
this.names = studentNames;
for (int i = 0; i < 5; i++){
for (int j = 0; j < 4; j++){
scores [i][j] = studentScores[i][j];
}
}
}
public String getName(int studentIndex){
return names.get(studentIndex);
}
public double getAverage(int studentIndex){
double total = 0;
for (int i = 0; i < 4; i++){
total += scores[studentIndex][i];
}
return (total / 4);
}
public char getLetterGrade(double avgScore){
if (avgScore >= 90 && avgScore <= 100){
return letterGrade[0];
}
else if (avgScore >= 80 && avgScore <= 89){
return letterGrade[1];
}
else if (avgScore >= 70 && avgScore <= 79){
return letterGrade[2];
}
else if (avgScore >= 60 && avgScore <= 69){
return letterGrade[3];
}
else if (avgScore >= 0 && avgScore <= 59){
return letterGrade[4];
}
return ' ';
}
public void getStudent(){
for (int i = 0; i < names.size(); i++){
System.out.println("\nStudent #" + (i+1)
+"\n\t\tName: " + names.get(i)
+"\n\t\tAverage: " + getAverage(i) + "%"
+"\n\t\tLetter Grade: " + getLetterGrade(getAverage(i))
+"\n\n");
}
}
}

I don't understand how much of what's going on in GradeBook relates to what you're doing in your main function. I see how in your main you're coming up with a single score based on the user's selection of a student and a test number. But once you have this user and score, I don't see how that matches up with the data in the double[][] studentScores table contained in GradeBook. What is that data? Where does it come from?
Your code in main seems to have a significant problem. index will always be 1 by the time it's used. Its value is not affected by what is entered as a student name. I think you mean for it to be. Also, I don't understand how the single integer score you come up with in main matches up with the avgScore accepted by the GradeBook. But ignoring all of that...
It seems like you'd have just a single GradeBook, right? So I think you'd instantiate just a single instance of it, and then you could use it to look up the student's name and to calculate the grade based on the student's score. Assuming that index matched up with the names list in GradeBook, and you somehow computed an averageScore, that would look something like this...
public class Main {
public static void main(String[] args) throws IOException {
...
GradeBook gradeBook = new GradeBook(...);
...
while (...) {
index = ...
...
averageScore = ...
...
studentName = gradeBook.getName(index);
grade = gradeBook. getLetterGrade(averageScore);
System.out.println(String.format("Student: %s. Grade: %s", studentName, grade));
}
The other use case I can see is that you'd calculate somehow calculate the studentScores table from the data you read in main, and then you could create a GradeBook with that to have it display all of that information. That would look like this...
studentScores = ...
...
GradeBook gradeBook = new GradeBook(studentScores);
gradeBook.getStudent()

Related

how to transverse arraylist

I need to know how to transverse my average function into this result function if u are getting ?
This is the main class:
import java.util.ArrayList;
import java.util.Scanner;
public class main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList < Calculations > students = new ArrayList < Calculations > ();
for (int i = 0; i < 5; ++i) {
Calculations s = new Calculations();
System.out.print("Enter name : ");
s.name = scan.next();
System.out.print("Eter percentage : ");
s.percetage = scan.nextDouble();
students.add(s);
System.out.println("Enter Mrks Obtained");
}
for (Calculations s: students) {
s.result();
for (Calculations i: students) {
s.Average();
}
}
}
}
This is result class:
import java.util.Scanner;
public class Calculations {
public String name;
public double percetage;
public int integer;
public void result() {
System.out.println((percetage >= 35.0 f ? (name + " Pass") : (name + " Fail")));
}
public void Average() {
// TODO Auto-generated method stub
int mark[] = new int[5];
int i;
float sum = 0;
float avg, perc;
Scanner scan = new Scanner(System.in);
System.out.print("Enter marks Obtained in 5 Subjects : ");
for (i = 0; i < 5; i++) {
mark[i] = scan.nextInt();
sum = sum + mark[i];
}
avg = sum / 5;
perc = (sum / 500) * 100;
System.out.print("Average Marks = " + avg);
System.out.print("\nPercentage = " + perc + "%");
}
}
for(Calculations s : students){
s.result();
//for(Calculations i : students){s.Average(); }
s.Average();
}
you dont have to loop your arraylist twice. try changing your code.
It was so hard to follow through your incomplete question, which is not specific either. Your program works fine in my eclipse. I would suggest following:
1) Check the name of the fields/ spelling in you Calculations class to match exactly as it's been used in the main class.
2) Since you're inputting String Scanner, try to read lines as follows:
s.name = scan.nextLine();
I hope it helped.

Counting occurrences of integers in an array program java

I am trying to find the occurrences of all integers submitted by the user into the program and so far here's what I got. It works but I don't think it's a legit way to do it, is there any way I can try to do this without using the list[10]=9999;? Because if I don't do it, it'll show out of boundary error.
import java.util.*;
public class OccurrencesCount
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int[] list = new int[11];
//Accepting input.
System.out.print("Enter 10 integers between 1 and 100: ");
for(int i = 0;i<10;i++){
list[i] = scan.nextInt();
list[10] = 9999;
}
//Sort out the array.
Arrays.sort(list);
int count = 1;
for(int i = 1;i<11;i++){
if(list[i-1]==list[i]){
count++;
}
else{
if(count<=1){
System.out.println(list[i-1] + " occurs 1 time.");
}
else{
System.out.println(list[i-1] + " occurrs " + count + " times.");
count = 1;
}
}
}
}
}
Personally, I think this is a perfectly good solution. It means that you can deal with the last group in the same way as all others. The only change I would make is putting the line list[10] = 9999; outside the for loop (there's no reason to do it 10 times).
However, if you want to use an array of length 10, you can change the line
if(list[i-1]==list[i])
to
if(i < 10 && list[i-1]==list[i])
If you do this, you won't get an ArrayIndexOutOfBoundsException from list[i] because the expression after the && is not evaluated when i == 10.
import java.util.*;
class OccurrencesCount {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int[] list = new int[101];
System.out.print("Enter 10 integers between 1 and 100: ");
for(int i = 0;i<10;i++) {
int x = scan.nextInt();
list[x]++;
}
for(int i = 1; i <= 100; i++)
if(list[i] != 0)
System.out.println(i + " occurs " + list[i] + " times ");
}
}
To store count of numbers from 1 to 100 you need to use a list of 100 integers each one storing the number of occurrences of itself. Better approach would be to use a Map.
I have made use of ArrayList and Collections package instead of regular arrays as a different flavor if it interests you check it out.
import java.util.*;
public class OccurrencesCount {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
//Accepting input.
System.out.print("Enter 10 integers between 1 and 100: ");
for (int i = 0; i < 10; i++) {
list.add(scan.nextInt());
}
Collections.sort(list);
Integer prevNumber = null;
for (int number : list) {
if (prevNumber == null || prevNumber != number) {
int count = Collections.frequency(list, number);
System.out.println(number + " occurs " + count + (count > 1 ? " times." : " time."));
}
prevNumber = number;
}
}
}
I got it figured out guys, only changed a couple of small things inside the conditions and everything went smoothly! Thanks for the help! Now I just need to find a way to restrict the inputs from going above 100.
import java.util.*;
public class CountOccurrences
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int[] list = new int[10];
//Accepting input.
System.out.print("Enter 10 integers between 1 and 100: ");
for(int i = 0;i<=9;i++){
list[i] = scan.nextInt();
}
//Sort out the array.
Arrays.sort(list);
int count = 1;
for(int i = 1;i<=10;i++){
if(i<=9 && list[i-1]==list[i]){
count++;
}
else{
if(count<=1){
System.out.println(list[i-1] + " occurs 1 time.");
}
else{
System.out.println(list[i-1] + " occurrs " + count + " times.");
count = 1;
}
}
}
}
}

Ending a program with ctrl+Z

import java.util.Scanner;
public class ClassAverage
{
public static void main(String args[])
{
String names[] = new String[50];
int scores[] = new int[50];
int entries = 0;
Scanner in = new Scanner(System.in);
//System.out.println("Enter number of entries");
//int entry = in.nextInt();
System.out.println("Enter the names followed by scores of students: ");
for(int i = 0; i < 50; i++)
{
names[i] = in.next();
scores[i] = in.nextInt();
entries++;
}
Average avg = new Average();
double average = avg.CalcAvg(scores,entries);
System.out.println("The class average is: " + average);
avg.belowAvg(scores,average,names,entries);
avg.highestScore(scores,names, entries);
}
}
class Average
{
Average()
{
System.out.println("The averages: ");
}
double CalcAvg(int scores[], int entries)
{
double avg;
int total = 0;
for(int i = 0; i < entries; i++)
{
total += scores[i];
}
avg = total/entries;
return avg;
}
void belowAvg(int scores[],double average,String names[], int entries)
{
for(int i = 0; i < entries; i++)
{
if(scores[i] < average)
System.out.println(names[i] + "You're below class average");
}
}
void highestScore(int scores[],String names[], int entries)
{
int max = scores[1];
for(int i = 0; i < entries; i++)
{
if(scores[i]>=max)
max=scores[i];
}
System.out.println("The maximum score is: " + max);
System.out.println("The highest score acheivers list: ");
for(int i = 0; i < entries; i++)
{
if(scores[i] == max)
System.out.println(names[i]);
}
}
}
im suppose to hold the ctrlkey press z and then press the enter key to end the program but how do i do that?
if you are wondering the program is to write a program that lets the user input student names followed by their test scores and outputs the class average, names of students below the average, and the highest test score with the name of student
Ctrl-Z is the DOS command code for end of input (the UNIX equivalent is Ctrl-D). All command line programs should support this because it allows you to pipe output from one as input to the other. Kudos to your teacher!
When this key combo is pressed, Scanner.hasNextLine() will return false. Here's an example of a loop that reads line until you hit Ctrl-Z on Windows (or Ctrl-D on Linux/Unix):
while (in.hasNextLine()) {
System.out.println("You wrote " + in.nextLine());
}
You can listen for the control-z character in your scanner:
String nextLine = in.nextLine();
if(nextLine.length == 1 && nextLine.charAt(0) == KeyEvent.VK_Z)
// end program

While loop not working

Hi I am fairly new to java and trying to familiarize myself to it by doing some exercises online.
How do i properly code the while loop so that everytime the user input is wrong it asks the same question again and does not proceed to the next line of code
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Array {
public static void main(String[] args) {
Scanner dataIn = new Scanner(System.in);
int entries = 0;
List<Integer> grade = new ArrayList<Integer>();
System.out.println("Enter number of students? ");
entries = dataIn.nextInt();
boolean checker = true;
while (checker){
for (int i = 0; i < entries; i++){
int input;
int addToList;
System.out.println("Enter grade for student: ");
input = dataIn.nextInt();
grade.add(input);
if (input >= 0 && input<= 100) {
}else {
System.out.println("invalid input try again..");
checker = false;
}
}
}
int sum = 0;
int count = grade.size();
double mean;
for (int grades : grade){
sum+= grades;
}
mean =(double)sum/count;
System.out.println("The Grades are: " + grade);
System.out.println("The number of elements in the Array is " + grade.size());
System.out.println("The average is: " + mean);
}
}
Your logic is backwards. You want the loop to continue if the input is incorrect. There are two ways to fix this:
Change while(checker) to while(!checker)
Change checker=false to checker=true after printing the error message. And set checker=false in the if branch.
It might help if you change the name of your checker variable to something that reads more directly. For example isInputCorrect reads very nicely when you write while(!isInputCorrect) and it also makes it more clear what the values of true and false represent.
try this :
boolean checker = true
for(int i=0;i< entries;i++){
int input;
System.out.println("Enter grade for student: ");
input = dataIn.nextInt();
while(checker){
if(input >= 0 && input<= 100){
grade.add(input);
checker = false;
}else{
System.out.println("invalid input try again..");
}
}
checker = true;
}
You could try this
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Array {
public static void main(String[] args) {
Scanner dataIn = new Scanner(System.in);
int entries = 0;
List<Integer> grade = new ArrayList<Integer>();
System.out.println("Enter number of students? ");
entries = dataIn.nextInt();
for (int i = 0; i < entries; i++) {
int input;
do{
input = dataIn.nextInt();
if (input >= 0 && input <= 100) {
grade.add(input);
}else{
System.out.println("invalid input try again..");
}
}while(!(input >= 0 && input <=100));
}
dataIn.close();
int sum = 0;
int count = grade.size();
double mean;
for (int grades : grade) {
sum += grades;
}
mean = (double) sum / count;
System.out.println("The Grades are: " + grade);
System.out.println("The number of elements in the Array is " + grade.size());
System.out.println("The average is: " + mean);
}
}
instead of doing while(checker)
make a loop for while(running)
then send it to the keyboard.nextInt()
if its the wrongAnswer than it will loop, if its correct than set running to false
and have code that follows the while loop

extra 0 digit when trying to add 2 arrays

I am working on a program that needs to calculate the sum of 2 large integers without using the biginteger class in java. I am stuck on my for loop which calculates the sum. I am getting an extra 0 so 30 + 30 = 600.
I am pretty sure it is because I am looping through the arrays the wrong way. I need to go the opposite way (starting from the right side like you would when adding numbers) but I can't seem to fix it without getting an out of array index error.
here is my code:
main:
import java.util.Scanner;
public class testLargeInteger
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String string1;
String string2;
int exp =0;
System.out.print("Enter the first integer: ");
//Store up the input string “string1” entered by the user from the keyboard.
string1 = input.next();
LargeInteger firstInt = new LargeInteger(string1);
System.out.print("Enter the second integer: ");
string2 = input.next();
//Store up the input string “string2” entered by the user from the keyboard.
LargeInteger secondInt = new LargeInteger(string2);
System.out.print("Enter the exponential integer: ");
//Store up the input integer “exp” entered by the user from the keyboard.
exp = input.nextInt();
LargeInteger sum = firstInt.add(secondInt);
System.out.printf ("First integer: %s \n", firstInt.display());
System.out.println("Second integer: " + secondInt.display());
System.out.println(" Exponent: " + exp);
System.out.printf (" Sum = %s \n", sum.display());
}
}
Large integer:
public class LargeInteger {
private int[] intArray;
//convert the strings to array
public LargeInteger(String s) {
intArray = new int[s.length()];
for (int i = 0; i < s.length(); i++) {
intArray[i] = Character.digit(s.charAt(i), 10); // in base 10
}
}
public LargeInteger( int[] array ) {
intArray = array;
}
//display the strings
public String display() {
String result="";
for (int i = 0; i < intArray.length; i++) {
result += intArray[i];
}
return result.toString();
}
//get first array
public int[] getIntArray() {
return intArray;
}
//ADD method to add 2 arrays together
public LargeInteger add(LargeInteger secondInt){
int[] otherValues = secondInt.getIntArray();
int maxIterations = Math.min(intArray.length, otherValues.length);
int currentResult; //to store result
int[] resultArray = new int[Math.max(intArray.length, otherValues.length) +1 ];
int needToAdd = 0; //to store result should be added next step
for(int i = 0; i < maxIterations; i++) {
currentResult = intArray[i] + otherValues[i];
resultArray[i] = currentResult % 10 + needToAdd; //if more than 9 its correct answer
needToAdd = currentResult / 10; //this is what you need to add on next step
}
resultArray[Math.max(intArray.length, otherValues.length) ] = needToAdd;
return new LargeInteger( resultArray );
}
}
I have tried changing the for loop in sum to something like this:
for(int i = maxIterations; i >= 0; i--)
That for loop is only one of your problems.
1] you are not adding the carry properly.
2] a stack is more appropriate here than an array.
With a stack (place code inside your method):
Note: You are calling the function with number.add(num2);
public class LargeInt{
private String number;
public LargeInt(String num){
this.number = num;
}
public String add(String num2){
Stack<Integer> adder = toIntegerStack(this.number);//UPDATE
Stack<Integer> addend = toIntegerStack(num2);//UPDATE
Stack<Integer> result = new Stack<Integer>();
int carry =0;
int tmp = 0;
while(!.adder.isEmpty && !addend.isEmpty()){
tmp = adder.pop()+addend.pop()+carry;
if(tmp > 10){
carry = tmp/10;
tmp%=10;
}else{
carry=0;
}
result.push(tmp);
}//while
while(!adder.isEmpty){
tmp = adder.pop()+carry;
if(tmp > 10){
carry = tmp/10;
tmp%=10;
}else{
carry=0;
}
result.push(tmp);
}//while
while(!addend.isEmpty){
tmp = addend.pop()+carry;
if(tmp > 10){
carry = tmp/10;
tmp%=10;
}else{
carry=0;
}
result.push(tmp);
}//while
//beyond this point the result is your answer
//here convert your stack to string before returning
}
}
UPDATE TO ANSWER COMMENT:
I am also editing above to call this function to fill stacks.
private Stack<Integer> toIntegerStack(String n){
Stack<Integer> stack = new Stack<Integer>();
for(char c: n.toCharArray())
stack.push(c-48);//ASCII
return stack;
}//toStack(String)
If you insist on using array, you must follow the same pattern with your array.
int indexA=0;
int indexB=0;
int[] result = new int[1+A.length>B.length?A.length:B.length];
int indexResult=result.length-1;
while(indexA < A.length && indexB <B.length){//inside is same idea
tmp = A[indexA++] + B[indexB++] + carry;
//... do here as for stacks for tmp and carry
result[indexResult--];
}
while(indexA < A.length){
//do as in stack version
}
while(indexB < B.length){
//do as in stack version
}
Your adding code assumes that the least significant digit is in array[0], but your reading code puts the most significant digit there. You should reverse the array after reading.

Categories