I am trying to create a program for a user entering information on books (Name, Author, Publishing year and price). And then I want to be able to get a list of the books' names published after 2000 and their average price.
At first, I thought of using arrays in an array, but after going through similar questions I chose to make a Book class:
public class Books {
public static String name;
public static String author;
public static int year;
public static float price;
public static float sum = 0.0F;
public static float avrg = 0.0F;
I don't know if the following are necessary, but I did it as I've seen it in a lot of examples:
public String getName () {
return name;
}
public String getAuthor () {
return author;
}
public int getYear () {
return year;
}
public float getPrice () {
return price;
}
Then, I am trying to take the user input and store my new objects in an array.
public static void main(String[] args) {
System.out.println("Please enter details for five books!");
Scanner in = new Scanner (System.in);
Books [] book = new Books[5];
int i = 0;
int j = 0;
int count = 0;
for (i=0; i < book.length; i++) {
System.out.println("Enter Book Title, Author Last Name, Year and Price:");
String name = in.next();
String author = in.next();
int year = in.nextInt();
float price = in.nextFloat();
}
And here I want to find the exact books and calculate their average price:
for (j=0; j<book.length; j++){
if (Books.year >= 2000) {
System.out.println("Books published after 2000:"+ Books.name);
sum = sum + Books.price;
count = count + 1;
}
}
avrg = sum/count;
System.out.println("Average price of books published after 2000:"+avrg);
Everything seems to be running smoothly till the part I want the names of the books (and average price) published. I get this as a result:
Please enter details for five books!
Enter Book Title, Author Last Name, Year and Price:
...
Average price of books published after 2000:NaN
It doesn't even show the names.I'm quite confused and I have no idea if this is the best way to do what I want to do. I will appreciate some help.
NaN means "Not a Number" and it signals a bad math operation, like zero divided by zero, that is your case: if no book meets the criteria count=0 and sum=0.0F and there you have it.
1) Follow Java naming conventions. The class should be Book because it is a singlular object.
public class Book {
And your array should be plural.
Book [] books = new Book[5];
2) Use instance variables, not class variables, for the properties that belong to an individual book. This requires you to remove static from name, author, year, and price.
3) "I am trying to take the user input and store my new objects in an array." Your code that you posted does not store new objects in the array. This explains both why no names are printed and why NaN is in your output, because the array is empty.
Try to store a new Book() into the array.
System.out.println("Enter Book Title, Author Last Name, Year and Price:");
Book b = new Book();
b.name = in.next();
...
books[i] = b; // stored
4) You need to loop over the Book objects in the array to access their properties. You can use an enhanced for loop since you don't need the index variable anyway.
double sum = 0;
for (Book b : books){
if (b.year >= 2000) {}
sum += b.price;
}
System.out.println(sum);
if (books.length > 0) {
System.out.println(sum / books.length);
}
5) Take that loop and make it a method. For example, public static double totalPriceOfBooksAfterYear(Book[] books, int year) and have it return sum. You can use that value to calculate the average.
Maybe you didn't share this part of your code but do you actually store the inputs in an Book object and then store it in the array? When you create the array it creates 5 Book objects with all null values.
When you're finding the years, none of them qualify since they're all null. This means the count is also staying as a 0. Dividing by 0 is giving the NaN error. The error doesn't show up in the
sum = sum + Books.price;
line because it's never reaching that state.
Also,
if (Books.year >= 2000)
is checking if the class has a year >= 2000 and not checking a specific object.
Try something like:
if(book[j].year >= 2000)
NaN means "Not a Number" .
If there aren't any books (Books.year >= 2000) in this condition it causes a division by zero error.Because your count variable is getting 0 .
In
avrg = sum/count; is not checking weather you have a count more than 0.
Place a if condition to check that,
if(count>=0){
avrg = sum/count;
System.out.println("Average price of books published after 2000:"+avrg);
}
For the book name use getName method insted of Books.name
As an example :
Books books = new Books();
System.out.println(books.getName());
And check your books for year 2000 or more like this
if(book[j].year >= 2000)
instead of
if(Books.year >= 2000)
Because you are using and array type object you need to specify which index you want to look into
Related
Can anyone help me here?? I have compiled and successfully run a program using Java which takes user inputs from an "inputdialog" box and displays this information back in the console along with a simple mathematical formula. The problem I cannot seem to overcome is when the data is input the user has an option to enter another set of the same data type but I need the console to register this as a second input. This is how far I am currently with the section of code and my ideas on how to make this work using an array but I have been informed that saving/storing the data as an object might be a better option?
private void enterCar()
{
String carInfo;
int carHours;
int i = 0;
int[] carNumb = new int[20];
double fee = Double.parseDouble("7.50");
double sum = 0;
final int MAX = 12;
{
carInfo = JOptionPane.showInputDialog("Please enter the license plate of the car");
carHours = Integer.parseInt(JOptionPane.showInputDialog("Enter the number of hours the car was parked (1-12):"));
System.out.printf("\n");
System.out.printf("Details for car "+carNumb+" entered:\n");
System.out.printf("License plate Hours Fee:\n");
System.out.printf(""+carInfo+" "+carHours+" $");
if (carHours == 1)
System.out.printf("%3.2f",fee*(carHours));
else if (carNum == 2)
System.out.printf("%3.2f",fee+4.50);
else if (carHours >= 3)
System.out.printf("%3.2f",3+(carHours*4.50));
System.out.printf("\n\n");
}
}
When I compile and run the console I get the line "Details for car [I#6659c656 entered". This line does change to something like "[I#7665c575" the next time I activate the option so I can assume that I may need to assign a value to the number differently?
I have tried the option that is show in the code provided as well as trying to activate a list using (1, 2, 3, ect) but this also just outputs that random line of numbers and letters.
I guess to simplify my question. I need to store 20 individual inputs from an 'InputDialog' box and store it for later access in a console.
I need to store 20 individual inputs from an InputDialog box and store it for later access in a console.
Use a loop such as for.
That information then gets stored as "Details for car 1 entered:" and then the information displayed.
As I said before, you should use index of array instead of array. And because array is zero-based index, so I use carNumb[i] + 1 to print out the order.
Then calculate fee and store to carNumb array.
Note that, your fee is double type => carNumb should be double type to store correct value.
Full code:
public void enterCar() {
String carInfo;
int carHours;
int i = 0;
double[] carNumb = new double[20];
double fee = Double.parseDouble("7.50");
double sum = 0;
final int MAX = 12;
for (; i < carNumb.length; i++) {
carInfo = JOptionPane.showInputDialog("Please enter the license plate of the car");
carHours = Integer.parseInt(JOptionPane.showInputDialog("Enter the number of hours the car was parked (1-12):"));
System.out.printf("\n");
System.out.printf("Details for car " + (carNumb[i] + 1) + " entered:\n");
System.out.printf("License plate Hours Fee:\n");
System.out.printf("" + carInfo + " " + carHours + " $");
carNumb[i] = getFee(fee, carHours);
System.out.printf("%3.2f", carNumb[i]);
System.out.printf("\n\n");
}
}
private double getFee(double fee, int hours) {
if (hours == 1) {
return fee;
}
if (hours == 2) {
return fee + 4.5;
}
if (hours >= 3) {
return 3 + hours * 4.5;
}
return 0;
}
Did I get your idea?
I want to prompt a user through command line using a Scanner, to select from a predefined index of a Rational Array. After that I want to display the value of a selected Rational Object. How can I go about doing so ? Below is the code I have so far
//Array of rational objects that I want to let user select from
Rational[] rationals = {new Rationa(2, 3), new Rational(2, 18), new Rational(3,12)};
//Method for displaying value of object
public static void displayValue()
{
System.out.println("Please select from index: ");
}
First create a .toString() method for the Rational class. Then you may print the array like this:
System.out.println(Arrays.toString(rationals));
Then you may get input like this:
Scanner sc = new Scanner(System.in);
int index = sc.nextInt();
Ensure an acceptable number was given:
if(index > -1 && index < rationals.length){
System.out.println(rationals[index]);
}else{
System.out.println("Please input an acceptable value.")
}
If you want to keep asking for an input, until an acceptable one is given, you it can be done by using a while loop:
boolean askAgain = true;
while(askAgain){
int index = sc.nextInt();
if(index > -1 && index < rationals.length){
System.out.println(rationals[index]);
askAgain = false;
}else{
System.out.println("Please input an acceptable value.")
}
}
EDIT: You may want to specify that the list starts at index 0, not 1.
EDIT2: .toString() example,
public class Person(){
private String name;
private int id;
public Person(String n, int id){
this.name = n;
this.id = id;
}
public String toString(){
return "Name: " + name + ", " + id;
}
}
The toString(); method for an object class is just meant for returning the "useful information" as a String. In this example, for a Person class, the toString() method just returns the name and id of the user. So, for your Rational class, you can adjust that method to properly turn the object into a String.
Usage:
Person p1 = new Person("Jake", 1);
System.out.println(p1.toString());
OUTPUT:
"Name: Jake, 1"
You will need to use a Scanner to read input from the console. To use Scanner, you need to import java.util.Scanner;
This line creates the new Scanner and attaches it to System.in, which is the standard input for the program.
Scanner console = new Scanner(System.in);
Now we can read an integer from input to select the index.
int index = console.nextInt();
After that, all you'll need to do is print out the value at index in your array.
For my homework, I had to write a program that prompts the cashier to enter all prices and names, adds them to two arrays lists, calls the method that I implemented, and displays the result and use 0 as the sentinel value. I am having difficulty coming up with a for loop in the method, I believe I have the condition right but I am having trouble with the statements. Any help would be greatly appreciated! Thanks.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<Double> sales = new ArrayList<Double>();
ArrayList<String> names = new ArrayList<String>();
System.out.print("Enter Number of Customers");
double salesAmount;
System.out.print("Enter Sales for First Customers");
salesAmount = in.nextDouble();
while(salesAmount != 0)
{
sales.add(salesAmount);
System.out.println("Enter Name of Customer: ");
names.add(in.next());
System.out.println("Enter the next sales amount, 0 to exit: ");
salesAmount = in.nextDouble();
}
String bestCustomer = nameOfBestCustomer(sales, names);
}
public static String nameOfBestCustomer(ArrayList<Double> sales, ArrayList<String> customers)
{
String name = "";
double maxSales;
for (int i = 0; i < sales.size(); i++)
{
sales.size(name.get); <== it keeps saying "cannot find the symbol variable get"
}
return name;
}
Don't use maxSales as the maximum in your loop. Use the count of number of customers. Inside the loop, check if sales.get(i) is greater than your current maxSales, and if it is...
(I will edit this and more if you still need. But this should go a long way.)
There are a couple possible issues here, but I'll stick to answering what I think is the question that you've asked.
In your nameOfBestCustomer method, you'll want to loop from 0 to the end of either of your ArrayLists (as they both should be the same size).
for (int i = 0; i < sales.size(); i++)
{
...
}
I'm having a few problems with my code, this is the over all goal of the program.
One of your professors hears of your emerging programming expertise and asks you to write a SINGLE program that can be used to help them with their grading. The professor gives three 50-point exams and a single 100-point final exam. Your program will prompt the user for the student’s name, entered as Firstname Lastname (i.e. Bob Smith), the student’s 3-exam scores and 1-final exam score (all whole numbers). Class size varies from semester to semester, but 100 is the limit (declare as a constant).
Read in information for ALL students before doing any calculations or displaying any output. Verify that the 3 exam scores are between 0-50 points and that the final is between 0-100 as they are entered. Declared minimums and maximums as constant so that they can easily be updated, as needed. If invalid, display an error message and allow the user to re-enter that invalid score. Once all student info is read in, display each student’s name in the format LASTNAME, FIRSTNAME (all uppercase), the student’s exam percentage (total of all exams plus final / total possible) to 1 decimal and the student’s final grade.
This is what I have:
import java.util.*;
import java.text.*;
public class Proj4 {
public static void main(String[] args){
Scanner s= new Scanner(System.in);
String input;
String again = "y";
final int MAX_STUDENTS = 100;
final int MIN_EXAM = 0;
final int MAX_EXAM = 50;
final int MIN_FINAL = 0;
final int MAX_FINAL = 100;
String[] names = new String[MAX_STUDENTS];
int [] exams = new int[MAX_STUDENTS * 4];
int student = 1;
do
{
System.out.print("PLease enter the name of student " + student + ": " );
for (int k = 0; k < 1; k++) {
names[k] = s.nextLine().toUpperCase();
}
for ( int i = 0; i < 4; i++){
if(i==3){
System.out.print("Please enter score for Final Exam: ");
exams[i] = s.nextInt();
}
else{
System.out.print("Please enter score for Exam " + (i+1) + ": ");
exams[i] = s.nextInt();
if((exams[0]<MIN_EXAM||exams[0]>MAX_EXAM)||(exams[1]<MIN_EXAM||exams[1]>MAX_EXAM)||(exams[2]<MIN_EXAM||exams[2]>MAX_EXAM)){
System.out.println("Invalid enter 0-50 only...");
System.out.print("Please re-enter score: ");
exams[i] = s.nextInt();
}
else if(exams[3]<MIN_FINAL||exams[3]>MAX_FINAL){
System.out.println("Invalid enter 0-100 only...");
System.out.print("Please re-enter score: ");
exams[i] = s.nextInt();
}
}
}
System.out.print("do you wish to enter another? (y or n) ");
again = s.next();
if(again!="y")
student++;
}while (again.equalsIgnoreCase ("y"));
System.out.println("***Class Results***");
System.out.println(names[1] + "," + names[0] + " " + "Exam Percentage: "+ ((exams[0]+exams[1]+exams[2]+exams[3])/(MAX_EXAM*3+MAX_FINAL)));
}
}
The problems i have have are:
figuring out how to assign the user entered test scores beyond just the first student, i believe i have it set up correct for just one, but it runs into a problem when i would move on to the second student.
For some reason that I cannot figure out the line
System.out.print("do you wish to enter another? (y or n) ");
again = s.next();
doesn't allow me to enter anything, not y not n not anything, so my program effectively ends there, it doesn't make sense to me because I've done it exactly like that before and it has worked.
other than that, if there are any other problems that you can see with my code pointing them out would be extremely helpful.
Thank you
EDIT-
new problem i am having, after changing to
if(!again.equalsIgnoreCase("y"))
student++;
}while (again.equalsIgnoreCase ("y"));
it lets me type things in now, but after i type in y it prints the next line as
Please enter the name of student 1: Please enter score for Exam 1:
I don't know why or what i need to change to fix it, any suggestions?
`if(again!="y")` is the culprit here
You should use equals() method to check string equality.
if(!again.equals("y"))
If you compare Strings in Java using the == or != operators then you are not actually comparing the values. Instead you are testing if the two Strings are the same Object.
This post explains String comparison well.
To do what you want, change if (again != "y") to if(! (again.equalsIgnoreCase("y")) )
EDIT
I believe your new problem stems from the first for loop you do inside your do loop. Each time you type "y" at the end of your do/while you are going to execute the entire
for (int k = 0; k < 1; k++) {
loop again. This is why after you type "y" you are seeing Please enter the name of student 1: Please enter score for Exam 1:
A "solution" to your new issue would be to make it so the outer for enclosed the inner one, looping through 4 exams for each student usually referred to as a "double for" or "nested for loop".
That said you would then be presented with the issue of having all the exams for ALL students in a single array.
I think now is the time to sit down and put some serious thought into the design of your program. It would be much easier for you if you used a Student object to represent a student and hold their exam scores, IMO. Then you could create an array of Students as opposed to two different arrays you have now.
Here are some "starter" steps (Not necessarily a complete list):
Make a Student class that has variables for the student's first & last name, as well as an array to hold that Students exam scores
In your main class create an ArrayList to hold all of the new Student objects you will be creating.
Do your do/while loop. At the beginning of the loop create a new Student object. Then ask for the Students name and exam scores (note that if you KNOW there will only be the 4 exam scores you don't have to do any extra logic there. You can simply ask for the 4 exam scores using a for loop, or if you want all at one time. if there are a variable number of scores you will have to do some sort of check)
Add the new Student you have created to the ArrayList of Students.
Once the person selects "n", loop through the ArrayList and print the information for each Student!
Your for (int k = 0; k < 1; k++) loop will execute only once (for one student) because you have it set up to execute only while k < 1, which will happen only once. As soon, as you increase k to 1, the loop will stop. I would change it to for (int k = 0; k < MAX_STUDENTS; k++) to make sure it will loop through until you reach the max number of students allowed.
Hey, so i have this hw assignment and i have to write a program that allows the user to input students names and grades and give back the higest lowest and average. The only problem is there is a max 50 students in the class(or so the sheet says) and there are only 10 students names and grades on it. How do i get the array to end after the last student?
static final int MAX = 50;
public static void main(String[] args)
{
int index, average;
int highest = 0, student = 1;
Scanner keyboard = new Scanner(System.in);
String [] students = new String[MAX];
int[] grades = new int[MAX];
System.out.println("Please enter the name of the student and their test grade");
System.out.print("Students: ");
for(index=0; index<MAX; index++)
{
students[index] = keyboard.nextLine();
student = student + index;
if(students[index]=="Done"))
{
student = student - 1;
continue;
}
}
System.out.print("Grades: ");
for(index=0; index<student; index++)
grades[index] = keyboard.nextInt();
averageMan(grades, student);
for(index=0; index<student; index++)
if(grades[index] < averageMan(grades, student))
System.out.println(students[index] + " Your test grade was " +
"below the class average. Step it up.");
for(index=0; index<student; index++)
if(grades[index] > highest)
highest = grades[index];
System.out.println("The highest test grade in the class goes to " +
students[highest] + " with a grade of " + grades[highest]);
}
public static int averageMan(int[] g, int s)
{
int index, sum = 0;
int averages;
for(index=0; index<s; index++)
sum = sum + g[index];
averages = sum / s;
return averages;
}
}
Use Collections, not arrays. Their api is a lot more usable.
Read the Collections Trail to get started.
If you want a drop-in replacement for an array, use a List, if you want uniqueness, use a Set.
You could loop round collecting student details until the user enters a specific token that indicates that they have finished entering details.
EDIT Which looks like what you're trying to do..... but continue goes to the next item in the loop. You want to break out don't you?
Initialize the students array with empty strings. Also Initialize the grades array with -1. In your loop for calculating average/highest/lowest, check for empty string and -1.
Try changing
student = student + index;
if(students[index]=="Done"))
{
student = student - 1;
continue;
}
to:
if(students[index]=="Done"))
{
break;
}
student = student + 1;
Then you will quit the entry loop when a student's name is input as "Done" and the variable student will contain the number of students that were input.
1) Hey, why are you doing this?
if(students[index]=="Done"))
{
student = student - 1;
continue;
}
2) you can divide code into smaller methods
3) you can use Collections API as someone suggested.
The easiest solution would be to use a collection class, like java.util.ArrayList instead of an array. If you have to use arrays, maybe you could reallocate the array each time you add a new Student? This page has an example of how to do that - How to resize an array in Java.
Your for loop has three parts, the middle part resolves to a true/false condition. It can be simple, like you have or complex, like this:
for(index=0; index<MAX && !done; index++)
Where done is a boolean that is false until you detect a value that indicates you want to stop then becomes true.
I would use a generic array list http://www.oracle.com/technetwork/articles/javase/generics-136597.html