Is this the correct way to use an IllegalArgumentException? - java

I'm trying to work on a Java assignment. This is what it asks:
Write a class named TestScores. The class constructor should accept an array of the test scores as its argument. The class should have a method that returns the average of the test scores. If an test score in the array is negative or greater than 100, the class should throw an IllegalArgumentException. Demonstrate. I need a file named TestScores and TestScoresDemo.
This is what I have so far. I know some of it is wrong and I need help fixing it:
class TestScores {
public static void checkscore(int s) {
if (s<0) throw new IllegalArgumentException("Error: score is negative.");
else if (s>100) throw new IllegalArgumentException("Error Score is higher then 100");
else if (s>89)throw new IllegalArgumentException("Your grade is an A");
else if (s>79 && s<90)throw new IllegalArgumentException("Your grade is an B");
else if (s>69 && s<80)throw new IllegalArgumentException("Your grade is an C");
else if (s>59 && s<70)throw new IllegalArgumentException("Your grade is an D");
else if (s<60)throw new IllegalArgumentException("Your grade is an F");
{
int sum = 0; //all elements together
for (int i = 0; i < a.length; i++)
sum += a[i];
}
return sum / a.length;
}
}
class TestScoresDemo {
public static void main(String[] args) {
int score = 0;
Scanner scanner = new Scanner(System.in);
System.out.print(" Enter a Grade number: ");
String input = scanner.nextLine();
score = Integer.parseInt(input);
TestScores.checkscore(score);
System.out.print("Test score average is" + sum);
}
}
I know the assignment calls for a try statement because in my book that's what I see with the IllegalArgumentException. Can anyone help me? I'm using Eclipse as an IDE.

Your TestScores class should have two members: a constructor that accepts an array of scores and a method that returns the average of the scores. The assignment isn't totally clear as to which of these should throw an IllegalArgumentException if a test score is out of range, but I'd make it the constructor (since that's what has the argument).
public class TestScores {
public TestScores(int[] scores) throws IllegalArgumentException {
// test the scores for validity and throw an exception if appropriate
// otherwise stash the scores in a field for later use
}
public float getAverageScore() {
// compute the average score and return it
}
}
You're on the right track with your TestScoresDemo class. It will first need to collect a set of scores into an array. Then it should construct a TestScores object. This is what needs to be inside a try/catch block because it can throw an exception. Then you just need to call getAverageScore() and do something with the result.

An exception is something used to define something that didn't go right on the normal flow of an application. You have to throw the IllegalArgumentException when the method checkScore is called and it finds any argument outside the range (between 0 and 100).
Your class should have this structure:
public class TestScore {
private int scores[]; //With setters and getters.
public TestScore(int scores[]) {
//Here, you set the scores array to the one on this class.
}
public int getAverage() {
//You do the average here, and since you need to iterate over the
//array to sum each value, you can check the value and if it's not
//ok you throw the IllegalArgumentException. No throws keyword
//required since this kind of exception (like NullPointerException
//and many others) are unchecked exceptions, meaning they can be
//thrown by a method and it does not need to specify them.
}
}
The test class should create a TestScore object with an int array as a parameter of its constructor. Then you make a testAverageScore method that has the try-catch statement on it, since it's required to call the getAverage method.
Hope that helps. Good luck!.
EDIT: IllegalArgumentException is an unchecked exception.

public class TestScores {
private final int[] scores;
public TestScores(int[] scores) {
this.scores = scores;
}
public int getAverage() {
int sum = 0;
if(scores.length == 0) {
return 0;
}
for(int score: scores) {
if(score < 0 || score > 100) {
throw new IllegalArgumentException("Score is not valid!");
}
sum += score;
}
return sum/scores.length;
}
}

Related

Take Average of an Array using Recursion

I'm trying to create a program that will take a user input, input that data into an dynamic array, and then recursively finds the average. The first part of my code works. This allows the newly created array to be passed to the method.
public static void main(String args[])
{
int i = 0;
int sum = 0;
double runningTotal = 0;
int classSize;
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter the class size: ");
classSize = keyboard.nextInt();
int newClassSize[] = new int[classSize];
for (i=0; i < newClassSize.length; i++)
{
System.out.println("Please enter the grade of the user at: " + (i + 1));
newClassSize[i] = keyboard.nextInt();
}
findAverage();
for (i=0; i < newClassSize.length; i++){
sum = sum + newClassSize[i];
}
System.out.println(Arrays.toString(newClassSize));
keyboard.close();
}
}
This is where I'm getting confused and confusing myself however. How would I pass the newly created array to the findAverage() method? I would then need to also have that be saved to an accumulator and then devided. Is there a better way to do this? This is my current findAverage() method but I'm confusing myself on my implementation.
public double findAverage(int classAverage, int baseCase, double runningAverage)
{
runningAverage = 0;
int sum = 0;
if (newClassSize.length - 1 > baseCase)
runningAverage = newClassSize.length;
return findAverage();
System.out.println("The class average is " + classAverage);
}
Hopefully I understood your question correctly but heres how to do it below.
The basic idea is that when the index reaches the length of the array in the
recursive function that's the base case. So all you have to do is add to the sum at each index point in the array, and just keep passing in the updated index and sum into the recursive function.
class Main {
public static void main(String[] args) {
int newClassSize[] = {1,2,3}; // User Input let say
double average = findAverage(newClassSize);
System.out.println(average);
}
public static double findAverage(int[] arr){
// Avoid division by zero error
if (arr.length==0){
return 0;
}
return findAverageHelper(arr,0,0);
}
public static double findAverageHelper(int[] arr, int index,int sum){
if (index==arr.length){ // Base Case
return (double) sum/arr.length;
}
// Increase index and add current value at index to sum
return findAverageHelper(arr,index+1,sum+=arr[index]);
}
}

Confusion about how to process lines in a text file as they are read

So I was given the following GradedActivity class:
public class GradedActivity
{
private double score; // Numeric score
public void setScore(double s)
{
if (s < 0)
score = 0.0;
else if (s > 100)
score = 100.0;
else
score = s;
}
public double getScore()
{
return score;
}
public char getGrade()
{
char letterGrade;
if (score >= 90)
letterGrade = 'A';
else if (score >= 80)
letterGrade = 'B';
else if (score >= 70)
letterGrade = 'C';
else if (score >= 60)
letterGrade = 'D';
else
letterGrade = 'F';
return letterGrade;
} }
and I was tasked with generating a constructor that accepts values for points Obtaned and pointsTotal as arguments, initializes them, and sets the corresponding score (points obtained divided by points total), accessors and mutators for pointsobtained and total.
So here is what I came up with:
public class ProgrammingAssignment extends GradedActivity
{
public int pointsObtained;
public int pointsTotal;
public ProgrammingAssignment(int p, int t)
{
pointsObtained = p;
pointsTotal = t;
}
public int getPointsObtained()
{
return pointsObtained;
}
public int getPointsTotal()
{
return pointsTotal;
}
public double getScore()
{
return pointsObtained / pointsTotal;
}
public void setPointsObtained(int p)
{
pointsObtained = p;
}
public void setPointsTotal(int t)
{
pointsTotal = t;
}
}
Everything compiles without error, but getScore isn't computing obtained/total (it comes back 0) in my test class:
public class PADemo
{
public static void main(String[] args)
{
ProgrammingAssignment p1 = new ProgrammingAssignment(28,30);
GradedActivity p2 = new ProgrammingAssignment(0,30);
System.out.println (p1.getPointsObtained());
System.out.println (p1.getPointsTotal());
System.out.println (p1.getScore());
System.out.println (p1.getGrade());
System.out.println (p2.getScore());
System.out.println (p2.getGrade());
p1.setPointsObtained(25);
p1.setPointsTotal(40);
System.out.println (p1.getScore());
System.out.println (p1.getGrade() == 'F');
}
}
How do I obtain the score (points obtained/points total) with getScore()
Test class returns:
28
30
0.0
F
0.0
F
0.0
true
Cars waiting: [a A123TR, a Z23YTU, a R23EWQ, a ERW345, a B12GFT...
Does that look correct? Why would you have the "a " at the beginning? That is not part of the car license. The "a " and "d " need to be removed BEFORE you add the license to the garage or queue.
creates a stack for cars in a garage (Max of 7)
a queue for cars waiting (max of 5)
Your basic logic appears wrong (to me).
When you get an "a" you do one of two things:
if there are less than 7 cars in the garage you add the car to the garage.
If there are 7, then if then are less the 5 cars in the queue, you add the car to the "queue".
When you get a "d" you:
first remove the car from the "garagee",
then you check the "queue". If there are cars in the "queue" then you move the car from the "queue" to the "garage".
So the logic might be structure something like:
while (...)
{
...
String[] data = line.split(" ");
if (data[0].equals("a"))
processArrival( data[1] );
else if (data[0].equals("d"))
processDeparture( data[1] );
}
I used the String.split(...) method which was suggested in your last question because it is a better test then to test the whole String for a specific character and your two pieces of data are separated into the array ready for processing. The data will now be split into two pieces of data: a) function
b) license
I used separate methods because the code is easier to read and logic for each function is contained in individual methods.

Calculating a minimum in object arrays and then using it in another calculation

I'm trying to understand how to take an object array that contains objects that have a name and 4 numbers and finding the lowest test grade. I have this Student object that has a name, bonus points earned, test 1 grade, test 2 grade, and a test 3 grade. I need to make sure that all 3 test grades added together don't go over 300 points.
I then need to find the lowest test grade of the 3 entered grades for each student and then be able to add the bonus points to them and print out the new grade.
I was going to create a method to loop through the Student object array and find the lowest grade for each student, have it create a new array with just the lowest grades and add that to the bonus points earned for each student but I'm not actually sure how to go about doing that part. This is the code for the Student object I've created so far:
public class Student
{
private String name;
private int bonusPoints;
private int test1;
private int test2;
private int test3;
public static final int MAX_TOTAL = 300;
public Student(String n, int bP, int g1, int g2, int g3)
{
setName(n);
setBonus(bP);
setTest1(g1);
setTest2(g2);
setTest3(g3);
}
//Setters & getters
//Method to check total of all 3 test grades
public boolean checkTotal(Student[] array)
{
int total = 0;
for (int i = 0; i < array.length; i++)
{
total += //I'm not sure how to refer to test1 ,test2, and test3 here
}
if (total > MAX_TOTAL)
{
return false;
}
else
{
return true;
}
}
}
So in order to add the 3 test totals together and check if it exceeds a maximum value. I would do something like this.
public boolean checkTotal()
{
int total = this.test1 + this.test2 + this.test3;
return total > MAX_TOTAL;
}
When referring to a classes variables within that class you can use the 'this' keyword to refer to the current instance of that class.
So a method call of that object would look something like this:
Student studentOne = new Student("Foo",90,80,70,10);
if(!studentOne.checkTotal())
//do something
else
//do something else
Also when returning a boolean you don't need an if/else most of the time. You can simply put
return /*your boolean expression here*/;

Find Average using Array of Objects/Object Array

this is such a simple problem but for some reason, I cant wrap my head around Array of Objects or Object Arrays. All I have to do is take in 5 user inputs, and create a class called Height, create object array and store user inputs into obj array and print the average. I'm kinda stuck.
class Height{
int total=0;
int count=0;
public Height(int y) {
total=total+y;
count++;
}
public void print() {
System.out.print("The average is: "+total/count);
}
}
public class ObjectArray {
public static void main(String[] args){
Scanner s=new Scanner(System.in);
System.out.println("Enter 5 heights in inches: ");
int[] x=new int[5];
int total=0;
for(int i=0;i<x.length;i++) {
x[i]=s.nextInt();
}
Height[] h=new Height[x.length];
for(int y=0;y<x.length;y++) {
h[y]=new Height(x[y]);
}
h.print();
}
}
Maybe I'm over complicating it. The problem right now is that I cannot invoke h.print();. I've tried different iterations, ex: taking out the print method and doing all the printing after every iteration.
Your approach is wrong. Your Height class appears to be responsible for the evaluation of the mean value. Hence, you should put all values inside a single Height instance, instead of generating a new instance for each user value.
However, h is an array of Heights object, while print() method is defined on a single Height instance. In order to call such method, you have to access one of the objects contained in h, that is h[0].print().
I'm assuming that your goal is simply to print the average of all the heights recieved via user input.
Your code in your main method is a tad confusing, so correct me if I'm wrong in any of the examples I give here. You should, instead of creating the x[] array, simply add the user input for the five values to Height.total in a for loop, and increase the Height.count variable by one each loop through. This should look something like this:
for (int i = 1; i <= 5; i++) {
// System.out.println("Please enter the next height: ");
Height.total += s.nextDouble();
Height.count++;
}
Then, you can run Height.print();.
I would also recommend adding a System.out.print(""); command to let the user know that they should enter the next value. That's the comment I left in the example code I gave above.
You have to design your Height in a way that match your requirement :
you need different Height with for each one a value
you need to know how many instances there is
For that, you need a private value, and a static counter :
class Height {
private int value = 0;
private static int count = 0; // static => nb of instances
public Height(int y) {
value = y;
count++;
}
public static int averageOf(Height... heights) {
return Arrays.stream(heights).mapToInt(h -> h.value).sum() / count;
}
}
To get the average, because it doesn't depend on a particular instance, you can have a static method, that sums all the value of the Height given and divide by the nb of instance
And use like :
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int nb = 5;
System.out.println("Enter " + nb + " heights in inches: ");
Height[] heights = new Height[nb];
for (int i = 0; i < heights.length; i++) {
heights[i] = new Height(Integer.parseInt(s.nextLine()));
}
System.out.println("Average is " + Height.averageOf(heights));
}

Seeking assistance for assignment to average an array of grades

I'll copy/paste the assignment, and then the progress I've made thus far. I'm truly not looking for someone to do the assignment, only some assistance to point me in the right direction as to where I'm going wrong? The program is running without error, however it's returning multiple results for a student when it should only be returning one. I can modify the grades and have it produce different results, so I know the math is being done, however I don't know why it's giving multiple (and different) results for a single student. I have been going over the code and cannot determine where I'm going wrong. My best guess is that it's somewhere in the OutputGrade method, I just can't find it.
Instructions:
Create a Java class called student with the following instance variables:
• private String studentName;
• private int [] grades; //an array of grades
Include setter and getter methods to set and get these 2 properties. The setter method for the grades instance array variable — setGrades() — should take a single argument which is an array of int with the grades already filled in. setGrades() should be used if statement(s) to make sure that each grade value in the array parameter is valid (between 0 and 100) — you will need to use a loop in conjunction with the if-statement(s) to do this efficiently. If a grade is out of bounds, setGrades() should set that grade value to 0. The array that you pass to setGrades() must hold between 3 and 5 grades.
Include a method called outputGrade() that averages up all the grades in the student grades array and then uses a switch statement to output grade conversions based on the following criteria:
• For values from 0–59, your program should output: “Student has failed this class”
• For values from 60–69, your program should output: “Student gets a D”
• For values from 70–79, your program should output: “Student gets a C”
• For values from 80–89, your program should output: “Student gets a B”
• For values from 90–100, your program should output: “Student gets an A”
Where “Student” is the actual name of the student.
Create a test class called TestStudent that instantiates 3 students and sets their names and grades and then calls outputGrade() for each student. For your 3 students, 1 must have 3 grades, 1 must have 4 grades, and 1 must have 5 grades. This is so you will have 3 different array sizes to pass to setGrades(). Make sure that for 1 student, setGrades() is called with 1 grade value that is out of bounds (less than 0 or greater than 100).
Code:
public class TestStudent {
public static void main(String[] args) {
Student student1 = new Student();
int[] grades1 = {15, 50, 5};
student1.setStudentName("Ernest Craft");
student1.setGrades(grades1);
student1.outputGrades();
Student student2 = new Student();
int[] grades2 = {95, 95, 95, 95};
student2.setStudentName("Steve Jones");
student2.setGrades(grades2);
student2.outputGrades();
Student student3 = new Student();
int[] grades3 = {105, -1, 72, 90, 88};
student3.setStudentName("Mary Smith");
student3.setGrades(grades3);
student3.outputGrades();
} // end method main
} // end class TestStudent
Student class:
public class Student {
private String studentName;
private int[] grades;
//constructor
public Student() {
}
public void setStudentName(String name) {
studentName = name;
} // end method setStudentName
public String getStudentName() {
return studentName;
} // end method getStudentName
public void setGrades(int gradeArray[]) {
grades = gradeArray;
for (int i = 0; i < gradeArray.length; i++) {
if (gradeArray[i] < 0 || gradeArray[i] > 100) {
gradeArray[i] = 0;
} // end if
} // end loop
} // end method setGrades
public int[] getGrades() {
return grades;
} // end method getGrades
public void outputGrades() {
int gradesTotal = 0;
int gradesAverage;
char letterGrade;
for (int i : grades) {
gradesTotal += i;
} // end loop
gradesAverage = gradesTotal / (grades.length);
if (gradesAverage >= 0 && gradesAverage <= 59) {
letterGrade = 'F';
} else if (gradesAverage >= 60 && gradesAverage <= 69) {
letterGrade = 'D';
} else if (gradesAverage >= 70 && gradesAverage <= 79) {
letterGrade = 'C';
} else if (gradesAverage >= 80 && gradesAverage <= 89) {
letterGrade = 'B';
} else {
letterGrade = 'A';
} // end if statement
switch (letterGrade) {
case 'A':
System.out.println(studentName + " gets an A.");
case 'B':
System.out.println(studentName + " gets an B.");
case 'C':
System.out.println(studentName + " gets an C.");
case 'D':
System.out.println(studentName + " gets an D.");
case 'F':
System.out.println(studentName + " gets an F.");
} // end switch
} // end method outputGrades
} // end class Student
Thanks for taking a look!
Ben
You forgot the break statements from your switch. If you don't break, it'll just keep executing everything until the end of the block!
This somewhat confusing "feature" is a leftover from C, and in most cases you'll want to end all your cases with a break, return or throw.

Categories

Resources