Debugger stops working - java

My program needs to allow the user to input an employee's name and total annual sales. When the user is finished adding employees to the array, the program should determine which employee had the highest sales and which had the lowest sales. It should then print out the difference between the two numbers.
In my code below, I have a totalPay class that holds the annual sales input by the user (it includes other variables and methods from a previous assignment that are not used here). The salesPerson class holds the employee's name and totalPay object, which includes their annual sales. (I realize this is overcomplicated, but I'm modifying my previous assignment rather than starting from scratch.)
When I run this code, it allows me to enter the name and sales, but when I enter "yes or no" to add another employee, it crashes and tells me there is a NullPointerException on line 58, noted in the code.
I've ran the debugger (without any breakpoints) and it just stops at line 46, noted in the code. It doesn't give an error message, it just doesn't update that variable and my "step into" buttons for the debugger grey out and I can't click them anymore. (I'm using NetBeans, if that's relevant.)
Any ideas would be much appreciated!
EDIT: Here is the output and error message.
Name? captain America
Input annual sales: 80
Add another employee? yes or no
no
Exception in thread "main" java.lang.NullPointerException at commission.Commission.main(Commission.java:58)
package commission;
//Commicaion calulator
import java.util.Scanner;
public class Commission
{
public static void main(String args [])
{
salesPerson[] emps = new salesPerson[10]; //Employee Array
String cont = "yes";
String n="";
double s=0;
int i=0;
salesPerson high = new salesPerson();
salesPerson low = new salesPerson();
// scanner object for input
Scanner keyboard = new Scanner(System.in);
//Enter in employee name
while (cont == "yes"){
System.out.print("Name? ");
n = keyboard.nextLine();
emps[i] = new salesPerson();
emps[i].setName(n);
//Loop of yes or no entering more employees
//If yes add another name if no continue with total Commision
//Enter in the sales amount of commistion
System.out.print("Input annual sales: ");
s=keyboard.nextDouble();
emps[i].pay.annual = s;
System.out.println("Add another employee? yes or no ");
keyboard.nextLine();
cont = keyboard.next(); //Line 46: Debugger stops here.
if (cont =="yes")
i++;
if (i==9){
System.out.println("You have reached the maximum number of employees.");
cont = "no";
}
}
i=0;
for (i=0; i<emps.length; i++){
if (emps[i].pay.annual > high.pay.annual) //Line 58: It claims the error is here.
high = emps[i];
if (emps[i].pay.annual < low.pay.annual)
low = emps[i];
}
double diff = high.pay.annual - low.pay.annual;
System.out.println("Employee "+low.getName()+" needs to earn "+diff+" more to match Employee "+high.getName());
// Output table for composation with increments of $5000
// int tempAnnual =(int) pay.annual;
// for (i=tempAnnual; i<= pay.annual; i+=5000)
// System.out.println(i+" "+ pay.getReward(i));
}
public static class totalPay
{
double salary=50000.0; //Yearly earned 50000 yr fixed income
double bonusRate1=.05; //bounus commission rate of 5% per sale
double commission; //Commission earned after a sale
double annual; //Sales inputted
double reward; // Yearly pay with bonus
double bonusRate2= bonusRate1 + 1.15 ; // Sales target starts at 80%
public double getReward(double annual)
{
double rate;
if (annual < 80000)
rate=0;
else if ((annual >= 80000) || (annual < 100000 ))
rate=bonusRate1;
else
rate=bonusRate2;
commission = annual * rate;
reward=salary + commission;
return reward;
}
}
public static class salesPerson
{
String name; //Employee Name
totalPay pay = new totalPay();
public void setName(String n) //Name
{
name=n;
}
public String getName()
{
return name;
}
}
}

You create this array of max size 10:
salesPerson[] emps = new salesPerson[10];
but only create and assign an object reference for each SalesPerson object entered. Since you only enter 1 name, only the 1st entry in the array is valid, then remaining 9 are null. You then attempt to iterate through the entire array (emps.length is 10 ):
for (i=0; i<emps.length; i++){
if (emps[i].pay.annual > high.pay.annual)
which leads to the NPE when indexing the first null reference. You need to change your loop to something like:
int numEntered = i; //last increment
for (i=0; i< numEnetered; i++){
if (emps[i].pay.annual > high.pay.annual)

It stops the debugger because it waits for your input using the keyboard. If you type the input and hit enter, the debugger will continue from there on.
By the way, your should read up on naming conventions and coding best practices for java

Your debugger is stopped because it's blocked on input coming in from the Scanner. This is specified in the documentation:
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.
That aside, you're fortunate to have entered that code block at all. You're comparing Strings incorrectly, so at a glance it'd look like you wouldn't enter that loop except under certain special circumstances. This is also the reason that your NPE occurs; you're initializing elements of your array under false pretenses (== with a String), so:
You may never initialize anything
You may only initialize the first thing (if (cont =="yes"))
I've only gone over a few of the high points, but for the most part, the blocking IO is why your debugger has stopped. The other errors may become easier to see once you start using .equals, but I'd encourage you to get an in-person code review with a classmate, tutor, or TA. There are a lot of misconceptions strewn about your code here which will make it harder to debug or fix later.

Related

why can int not be deferenced?

I'm writing a while loop program and this problem keeps staying here and I'm not sure how to fix it. Keeps displaying "int cannot be dereferenced". I have done a ton of research on this problem and I don't know what am I doing wrong: read on google, read on StackOverflow and so on, but I don't know what to do. Tried the parsing technique but kept saying "scanner cannot convert string to int" Here is my code, any help would be appreciated. I could have declared the variable in the if and else if conditions, but I would like to keep track of what I am doing and I believe it's better to not repeat codes. (such as print out statement)
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner Data = new Scanner (System.in);
final int goldplated = 100, fourteen = 500, eighteen = 1000;
int total = 0, count = 1, size = 0;
String GetInfo = "";
System.out.println("How many times do you want to purchase:");
int EnterData = Data.nextInt();
while(count<=EnterData){
System.out.println("What Kind of Chain do you want to buy? Below are the list of options: \n 1 - gold plated \n 2 - 14k gold \n 3 - 18k gold");
//GetInfo = Data.next();
if (Data.equals("1")||Data.equals("gold plated")){
System.out.println("Please specify the length of the chain.");
size.nextInt();
total = size * goldplated;
}else if(Data.equals("2")||Data.equals("14k gold")){
System.out.println("Please specify the length of the chain.");
size.nextInt();
total = size * fourteen;
}else if(Data.equals("3")||Data.equals("18k gold")){
System.out.println("Please specify the length of the chain.");
size.nextInt();
total = size * eighteen;
}else{
System.out.println("Invalid operation");
} count++;
total+= size.nextInt();
System.out.println("This is your price: " + total);
}
}
}
nextInt() is a method in the Scanner class. So when you write something.nextInt(), the something part will have to be a Scanner object. And in your case, you've got a Scanner object, which you've called Data (not the best name for it, but never mind).
If you write Data.nextInt(), your program will wait for the user to type in a number, and return that number. That's what you want, but you'll want a variable to assign that number to, so that you can use it. That variable is size. So every time you've written size.nextInt(); in your program, what you actually need to write instead is size = Data.nextInt(); - that is, call the method on the Data object, and assign the result to the size variable.

How to solve this program?

I found this Java exercise :
Create a class Sales that has TotalSales (double) , Commission (double),
Commissi onRate (double), and NoOfItems (integer).
write a java application that asks the user to enter the Total Sales and the number of items then calculates the commission and prints it out.
The commission rate should be as following:
Condition :
Less than 500, commissionRate is 0
Greater than or equal 500 or Number of Items >= 5, commission rate is 5%.
Grater than or equal 1000 or Number of items >=10, commission rate is 10%
..
I wrote this code:
Main Class :
import java.util.Scanner;
public class testSales {
public static void main(String[] args) {
Sales s1 = new Sales();
Scanner get = new Scanner(System.in);
System.out.println("Enter total Sales");
s1.totalSale = get.nextDouble();
System.out.println("Enter number of Items");
s1.NoOfItems = get.nextInt();
if(s1.totalSale < 500){
s1.commission = s1.commissionRate = 0;
}
else if(s1.totalSale >= 500 && s1.totalSale <= 999 || s1.NoOfItems >= 5 && s1.NoOfItems <=9){
s1.commission = s1.commissionRate = s1.totalSale * 5 / 100;
}else if(s1.totalSale >= 1000 || s1.NoOfItems >=10) {
s1.commission = s1.commissionRate = s1.totalSale *10/100;
}
System.out.println(s1.commission);
}
}
One problem in your code is the case where NoOfItems > 5 but totalSale < 500. For this case, the commission will incorrectly be set to 0 because the first if statement eats it.
Please try to be more specific with your question. "this doesn't work and I don't know why" is not easy to help with.
Aside from the point brought up by HedonicHedgehog, there are a few other things to consider:
The sales class only has two global variables, which corresponds to the information entered by the user. The other two fields, commission and commissionRate, are calculated values. Therefore, there is no need to create variables for them. Just add to the sales class accessor methods (getters) that return these values. For example, below is my getCommission() method:
public double getCommission()
{
return totalSales * getCommissionRate();
}
Of course, you can see this method is dependent upon the getCommissionRate() method. Because there is a gap on your requirements with total items, I am ignoring it for now:
public double getCommissionRate()
{
if (totalSales < 500)
return 0;
if(totalSales < 1000)
return .05;
else
return 0.1;
}
Alternatively, you could create a LOCAL commission variable, and set the value before returning it. It is a good programming practice to limit the scope of your variables. In this case, there is not a good reason to have a global commission or commissionRate variables.
Lastly, your test class is simplified because all you need to do is to prompt the user for the two needed fields, and it simply spits out the output because the Sales class provides the calculation needed to figure out the rest:
public static void main(String[] args)
{
Sales s1 = new Sales();
Scanner input = new Scanner(System.in);
System.out.print("Enter total Sales");
s1.setTotalSales(input.nextDouble());
System.out.print("Enter number of Items: ");
s1.setNumOfItems(input.nextInt());
System.out.printf("$%.2f", s1.getCommission());
input.close();
}
I used the printf() method to format the output string. The following is a sample run:
Enter total Sales: 503.45
Enter number of Items: 5
$25.17
Enter total Sales: 1003.67
Enter number of Items: 19
$100.37
Enter total Sales: 45.00
Enter number of Items: 19
$0.00
Remember that this example ignores the number of items because of the reasons already mentioned. Once you figure out what needs to be done to cover of the gap in the requirements, you can modify this code to do the rest. Also remember that your Sales class only requires two fields: totalSales and numOfItems. The other to components (commission, and commissionRate) are calculated; therefore, no global variable or setter methods needed. Just the two getter methods I provided.

Program not displaying everything it's supposed to

I am writing an inventory program for a book store that is comprised of two classes and multiple methods within these classes.
The method I'm having the most trouble with is my purchase() method which is supposed to interactively process a purchase, update the array after the purchase, and display totals for items sold and total amount of money made that day.
The method is supposed to follow these 10 steps:
Ask the user to enter the ISBN number of the book they'd like to purchase.
Search the array for the object that contains that ISBN.
If the ISBN isn't found in the array, display a message stating that we don't have that book.
If the ISBN is found but the number of copies is 0, display a message saying the book is out of stock.
If the ISBN is found and the number of copies is greater than 0, ask the user how many copies they'd like to purchase.
If the number they enter is greater than the number of copies of that book in the array, display a message stating that and ask them to enter another quantity.
When they enter a 0 for the ISBN, the Scanner is supposed to close
Once the purchase is complete I need to update the array by subtracting the number of copies of that particular book that was purchased.
Print the updated array.
Display a count of how many books were purchased, and how much money was made from the purchase.
But as my code is written, after the Program prompts me to enter an ISBN, nothing happens, it just continually lets me enter numbers with no additional output.
Here is the code I have for this method. I'm pretty sure it's probably an issue with my loop as I'm not very good with looping. Can anyone spot what I'm doing wrong?
public static Book[] purchase(Book[] books) {
int itemsSold = 0;
double totalMade = 0;
double price;
int copies;
String isbn;
Scanner input = new Scanner(System.in);
int desiredCopies = 0;
int index;
double total = 0;
System.out.println("Please enter the ISBN number of the book you would like to purchase: ");
String desiredIsbn = input.next();
for (index = 0; index < books.length; index++) {
if (books[index].getISBN().equals(desiredIsbn) && books[index].getCopies() > 0) {
System.out.println("How many copies of this book would you like to purchase?");
if (!books[index].getISBN().equals(desiredIsbn))
System.out.println("We do not have that book in our inventory.");
if (books[index].getISBN().equals(desiredIsbn) && books[index].getCopies() == 0)
System.out.println("That book is currently out of stock.");
desiredCopies = input.nextInt();
}
if (desiredCopies > books[index].getCopies())
System.out.println("We only have " + books[index].getCopies() + "in stock. Please select another quantity: ");
desiredCopies = input.nextInt();
books[index].setCopies(books[index].getCopies() - desiredCopies);
if (input.next().equals(0))
System.out.println("Thank you for your purchase, your order total is: $" + total);
input.close();
total = books[index].getPrice() * desiredCopies;
itemsSold += desiredCopies;
totalMade += total;
System.out.print(books[index]);
System.out.println("We sold " + itemsSold + " today.");
System.out.println("We made $" + totalMade + "today.");
}
return books;
}
Any help would be greatly appreciated.
You are not matching every possible condition
Your if statements aren't covering all the possible permutations of conditions apparently.
You should use always use an if/else if/else block to make sure you cover all your conditions. Outside this there is absolutely no way for anyone to provide any actual solution with so little to go on.
Also
Scanner and StringTokenizer are two of the worst designed classes in the JDK outside Date and Calendar. They cause endless trouble for new people and are avoided by the veterans.

Cannot use arrays or foreach loops to iterate over list of data and print out only certain values

The Prompt:
A program that accepts a candy name (for example, “chocolate-covered blueberries”), price per pound, and number of pounds sold in the average month, and displays the item’s data only if it is a best-selling item. Best-selling items are those that sell more than 2000 pounds per month.
b. A program that accepts candy data continuously until a sentinel value is entered and displays a list of high- priced, best-selling items. Best-selling items are defined in Exercise 2a. High-priced items are those that sell for $10 per pound or more.
Here is an example of a good design in operation:
High-priced, Best-selling Candy
Fudge $12.50 4500 lbs
Vanilla Creme $13.75 2200 lbs.
Fudge, 12.50, 4500 Jawbreakers, 6.50, 5500 Chocolate, 14.00, 790 Butterscotch, 9.50, 4500 Vanilla Creme, 13.75, 2200
Item that sold most pounds: Jawbreakers
but the problem I am having is that my teacher is not letting me use for loops, or arrays. And I do not want to define multiple instances of the same variable because it is finite to a certain amount.... What would be the most efficient way of doing this?
start
// Declarations
num QUIT = "Y";
final String HEADING = "High Priced, Best Selling Candy" + "\n" + "\n";
final String HSPS = candyName + " " + candyPrice + " " + candySold + " ";
final String MOSTSOLD = "Item that sold the most pounds is "
while <> QUIT;
enterCandy();
printHighPriceBestSelling();
printSoldMostPounds();
endwhile;
stop
entercandy()
String candyName = "poop";
double candyPrice = 0.0;
double candyWeight = 0.0;
int candySold = 0;
output "Please enter name of candy.";
input candyName;
output "Please enter candy price.";
input candyPrice;
output "Please enter pounds sold.";
input candySold;
printHighPriceBestSelling()
if(candySold > 2000 && candyPrice > 10)
{
output HEADING;
output HSPS;
}
else
{
output "There were/are no best selling, high priced candy!"
}
printSoldMostPounds();
//There is no basis for comparison.
There are only two ways of doing this. Create lots of different, artbitrary, and predefined variables to be filled by the loop until they are overwritten. Lets say 10. Or create an array. I am sure there is an overly complex way of doing it with nested if/switch/while loops, but why teach us/force us to use the ugly inefficient way?
output "MOSTSOLD ";
I'm assuming that, besides arrays, you're teacher isn't allowing you to use any standard Collection objects.
You could always just build your own LinkedList of entered candy orders--it's ugly, but it would work. A single "link" in the chain would look like this
public class CandyOrderLink {
private String candyName;
private Double candyPrice;
private Double orderAmount;
private CandyOrderLink nextOrderLink;
public CandyOrderLink(String candyName, Double candyPrice, Double orderAmount) {
this.candyName = candyName;
this.candyPrice = candyPrice;
this.orderAmount = orderAmount;
}
public CandyOrderLink getNextLink() {
return nextOrder;
}
public void setNextLink(CandyOrderLink nextOrderLink) {
this.nextOrderLink= nextOrderLink;
}
public String getCandyName() {
return candyName;
}
public Double getCandyPrice() {
return candyPrice;
}
public Double getOrderAmount() {
return orderAmount;
}
}
Not sure if I'm quite grasping the point of the assignment, but using a list data-structure to keep track of all orders will work. Just build a link for each entry (candyName, price, amount) and set that link as the next link of the previous one. At the end of input, iterate through the list by repeatedly calling getNextLink() on each link and printing information (if appropriate). Here is Wikipedia's article on linked lists: http://en.wikipedia.org/wiki/Linked_list
From the problem's description, I see no need to store the data entered so that it can be sorted. Both a and b state simple conditions for displaying a candy: greater than 2,000 pounds and at least $10/lb. You can print each entry immediately after it is entered.
However, your example output implies that you must pick the single best-selling candy which contradicts the description. Which is correct?

Java method passing/ordered logic inquiry

Let me first make it clear that this is for an assignment. I'm very new to programming so all guidance is greatly appreciated. The program I have to calculate is a parking fee charge for a $2.00 minimum for 3 hrs or less, .50 cents per additional hr, and charge is capped at $10/ per 24 hr period. Program must display most recent customer charge as well as running total. Constants must be initialized, Math.ceil must be used, and method calculateCharges must be used to solve each cust's charge. I get uber errors when I attempt to run this program, and you'll probably laugh when you see it, but where have I erred? I'm not looking for the answer to be handed to me, just looking for the logic behind how to get to the correctly written program. Please help!
package Parking;
import java.util.Scanner;
public class parking
{
private static final double THREE_HOURS = 2.00;
private static final double PER_HOUR_COST = .50;
private static final double WHOLE_DAY_COST = 10.00;
public static void main (String [] args)
{
double hoursParked = 0;
double cumulativeCharges = 0;
double storage1 = 0;
double storage2 = 0;
Scanner input = new Scanner(System.in);
System.out.print("\nThis program displays the charge for the most recent customer");
System.out.print(" as well as the running total of yesterday's receipts\n");
do
{ System.out.printf("Enter an number between 1-24 for hours parked in garage or -1 to quit:");
hoursParked = input.nextDouble ();
}
while((hoursParked > 0)&&(hoursParked <= 24)&&(hoursParked != -1));
if( hoursParked <= 3)
System.out.printf("Most recent customer's charge was: %.2f\n" , THREE_HOURS);
storage1 += THREE_HOURS;
if(hoursParked >= 18.01)
System.out.printf("Most recent customer's charge was:%.2f\n" , WHOLE_DAY_COST);
storage2 += WHOLE_DAY_COST;
double result = calculateCharges(hoursParked * PER_HOUR_COST);
System.out.printf("Most recent customer charge was:%.2f\n" , result);
cumulativeCharges = storage1 + storage2;
System.out.printf("Running total of yesterday's receipts is:%.2f\n" , cumulativeCharges);
} // end main
public static double calculateCharges (double hoursParked)
{
Math.ceil(hoursParked);
double total = hoursParked * PER_HOUR_COST;
return total;
} // end method calculateCharges
} // end class parking
In your while condition, the third condition is useless because if the value is positive, that necessarily means it is different than -1.
In your function you want to calculate the cost of parking time but you give as parameter a cost instead of a number of hours when you call your function. Is that normal? With that you will calculate the cost of the cost instead of the cost corresponding to a number of hours.
public static double calculateCharges (double hoursParked)
and
double result = calculateCharges(hoursParked * PER_HOUR_COST);
There's a couple things here.
Your while condition is checked at the end of the do loop, it is what allows you to break after reading hoursParked. Thus, the only way you are going to reach the code outside of the do loop (after the while), is if hoursParked is -1.
Secondly, when you do not have braces for your if conditions, you are only executing the first line after it, aka. the System.out.print's. Therefore, your first if condition will execute (printing the string), then storing 2.00 in storage1. Similarly, the second if condition will execute (printing the string), then storing 10.00 in storage2.
Because hoursParked is always -1, you are passing in (-1 * .5) to calculateCharges. You are not storing the result of Math.ceil() so it effectively does nothing. You are then returning (-.5 * .5) = -.25.
cumulativeCharges is just adding 2 + 10 in every case.
Suggestions - make sure you are encapsulating the code you want to execute inside the do loop, and only break after you have done your calculations on hoursParked.

Categories

Resources