Have to enter input twice rather than once to continue program - java

I'm writing a program for buying tickets. So far this is my code.
package prog;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Scanner;
public class assign {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Which type of ticket do you require stand or terrace?");
char tickType=sc.next().charAt(0);
System.out.println("How many tickets do you require?");
byte amount=sc.nextByte();
if (amount<5)
System.out.println("How many tickets for students?");
byte stud=sc.nextByte();
if (amount>=5)
System.out.println("You are entitled to a 12% discount.");
else if (stud>0)
System.out.println("discount will be 10%");
else
System.out.println("You are not entitled to a discount");
if (tickType=='S'||tickType=='s')
System.out.println("Ticket cost is\t "+amount*20.00);
else
System.out.println("Ticket cost is\t"+(amount*15.00));
double stand= amount*20.00;
double terrace= amount*15.00;
//VAT is 23%
When I get to
System.out.println("How many tickets do you require?");
byte amount=sc.nextByte();
if I enter 5 or a higher number I have to enter it twice rather than once can somebody tell me why this is happening please?

You have a flaw in the logic: if amount is less than five, then you print "How many tickets for students?", but then read the value even if amount is greater or equal to five.
The best solution would be to declare byte stud = 0; before if (amount < 5), and then correct the if statement to include two lines:
byte stud = 0;
if (amount < 5) {
System.out.println(...);
stud = sc.nextByte()
}
This way, you read the value for stud only if amount is less than 5.

You must be entering first value greater than 5. In this scenario it will not pass the condition if(amount<5) thus not printing s.o.p and expecting input because of next line which is byte stud=sc.nextByte();

Related

using a while loop for user to input multiple int and find the max and min

so my homework question is prompt user a series of integers and find the max and min of those integer. Use a loop and -99 to break loop.Below is my code but my question is that is there a shorter way for this? feel free to comment and i appreciate your time reading this.
Scanner input=new Scanner(System.in);
int num1,num2,max,min;
System.out.print("enter a number: ");
num1=input.nextInt();
System.out.print("enter another number: ");
num2=input.nextInt();
max=Math.max(num1,num2);
min=Math.min(num1,num2);
while (num2!=-99){
System.out.print("enter a number or -99 to stop: ");
num2=input.nextInt();
if(num2!=-99){
max=Math.max(max,num2);
min=Math.min(min,num2);
}
}
System.out.println("largest is: "+max);
System.out.println("Smallest is: "+min);
You check for the condition of num2 != -99 twice, remember the first rule of programming, do not repeat yourself
You could save some lines by checking for min and max before asking for the next input. This way you do not need to check if num2 != -99 inside the while loop
Ok So after working on this. I finally did it. It does have a small bug, but I really don't wanna fix it so if anyway wants to edit this then be my guest.
Scanner input = new Scanner(System.in);
int studentNum = 0;
ArrayList<Integer> calc = new ArrayList<Integer>();
while (studentNum <= 100) {
System.out.print("Enter a number: ");
calc.add(input.nextInt());
studentNum += 1;
if (input.nextInt() == -99) {
break;
}
}
int min = Collections.min(calc);
int max = Collections.max(calc);
for (int i = 0; i < calc.size(); i++) {
int number = calc.get(i);
if (number < min)
min = number;
if (number > max)
max = number;
}
System.out.println("Max is " + max);
System.out.println("Min is " + min);
This does exactly what you want. However, there was a problem checking for the exit signal.
if (input.nextInt() == -99) {
break;
}
this checks if the userInput is equal to -99 then stops the program and calculates and prints out the min and max. However the tiny bug is that it will first ask for your number to add to the array list and then it will ask again for the userInput to check if its equal to -99. But overall it does exactly what you want.
Hope this helped.
EDIT I will work on it later and find a way to fix that bug if no one else knows.
Your code has one minor bug and can be slightly optimised. Things you might want to consider:
What happens (and what should happen) when the user types -99 as the second number?
Do you necessarily need to have at least 2 numbers? Wouldn't one be enough for the program to exit gracefully? The first number would then be both min and max.
Can you re-order your code lines so that the duplicated (num2!=-99) is not necessary anymore?
Pro questions:
What happens if the user types in some letters? How can you handle that case?
What happens if the user types in a super high number (bigger than the maximal integer)?
What happens if the user presses enter without typing any number?
Nitpicking:
Using + to concatenate strings and numbers is a bad idea because it's hard to remember where it works and where it doesn't.
Better look into String.valueOf(int i) and String.format(String format, Object... args)
Look up Google's Java Coding Style for formatting your code in best readable way. In many editors you can automatically apply the style. It describes things like where to use spaces or what to indent.

Debugger stops working

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.

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.

multiple while loop comparison (BigDecimal and > 10 )

This is my first post and I have been searching google and stack overflow for the past 24 hours and can not seem to pin down my problem.
I am creating a simple square root program. For the input section I start a 'while' loop. I need it to compare two conditions.
1. is the input a number
2. is the input a number over ten.
I was successful in creating the original program, however I ran into a small problem while debugging. When I put in a vary large decimal or number I would get a run time error.
I discovered that I could use BigDecimal() to solve this problem.
However I am now running into a logic error that I cannot solve no matter how many times I search the internet.
The two conditions that I use in the while loop are:
while (!scan.hasNextBigDecimal() || (inputNumberBig.compareTo(SENTINAL)>0))
This will make sure that there is a BigDecimal, but will not make sure that the input number is over ten.
Here is the whole program
import java.math.BigDecimal;
import java.util.Scanner;
/**
#author Mike
*/
public class SquareRootingWithoutBigDecimal
{
public static void main( String [] args )
{
Scanner scan = new Scanner(System.in);
double inputNumber = 0.00;
double rootedNumber = inputNumber;
BigDecimal inputNumberBig = new BigDecimal(0.00);
BigDecimal SENTINAL = new BigDecimal(10.00);
String garbage;
double garbageD = 0.00;
System.out.println("Please Enter a number to be Square rooted"
+ "\nThe number must be 10 or greater ");
while (!scan.hasNextBigDecimal() || (inputNumberBig.compareTo(SENTINAL)>0))
{
garbage = scan.nextLine();
System.out.println("Please Enter a number to be Square rooted"
+ "\nThe number must be 10 or greater ");
}
inputNumberBig = scan.nextBigDecimal();
inputNumber = inputNumberBig.doubleValue();
rootedNumber = inputNumber;
do
{
rootedNumber = Math.sqrt(rootedNumber);
System.out.println(rootedNumber);
} while (rootedNumber >= 1.01 );
}
Any and all help is much appreciated.
-Mike
inputNumberBig = scan.nextBigDecimal();
inputNumber = inputNumberBig.doubleValue();
These HAVE to go before you while loop for your logic to work.
Also,
while (!scan.hasNextBigDecimal() || (inputNumberBig.compareTo(SENTINAL)>0))
I could see this causing a problem. You should use && instead of ||

Categories

Resources