When I enter input that satisfies everything and doesn't trigger any of my errors, the program just exits after last input like it is skipping over the for or if loop.
Also after System.out.printf("Enter the name of your second species: "); it won't allow for any input, it just skips to the next prompt. I'm not sure why that is. The section above it asking for the first species' info works fine.
import java.util.Scanner;
public class HW2johnson_pp1 {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
System.out.printf("Please enter the species with the higher" +
" population first\n");
System.out.printf("Enter the name of your first species: ");
String Species1 = keyboard.nextLine();
System.out.printf("Enter the species' population: ");
int Pop1 = keyboard.nextInt();
System.out.printf("Enter the species' growth rate: ");
int Growth1 = keyboard.nextInt();
System.out.printf("Enter the name of your second species: ");
String Species2 = keyboard.nextLine();
System.out.printf("Enter the species' population: ");
int Pop2 = keyboard.nextInt();
System.out.printf("Enter the species' growth rate: ");
int Growth2 = keyboard.nextInt();
if (Pop2 > Pop1) {
System.out.printf("The first population must be higher. \n");
System.exit(0);
}
Species input1 = new Species();
input1.name = Species1;
input1.population = Pop1;
input1.growthRate = Growth1;
Species input2 = new Species();
input2.name = Species2;
input2.population = Pop2;
input2.growthRate = Growth2;
if ((input1.predictPopulation(1) - input2.predictPopulation(1)) <=
(input1.predictPopulation(2) - input2.predictPopulation(2))){
System.out.printf(Species2 + " will never out-populate " +
Species1 + "\n");
}
else {
for (int i = 0; input2.predictPopulation(i) <=
input1.predictPopulation(i); i++) {
if (input2.predictPopulation(i) == input1.predictPopulation(i)) {
System.out.printf(" will out-populate \n");
}
}
}
}
}
This for the predictPopulation():
public int predictPopulation(int years)
{
int result = 0;
double populationAmount = population;
int count = years;
while ((count > 0) && (populationAmount > 0))
{
populationAmount = (populationAmount +
(growthRate / 100) * populationAmount);
count--;
}
if (populationAmount > 0)
result = (int)populationAmount;
return result;
}
This is because you never print anything after Species 2 overtakes Species 1, except in the very special case that Species 2 and Species 1 have exactly the same population in some year.
This is because, when you enter Species 1's growth rate, you enter an integer, and then press Enter. keyboard.nextInt() swallows the integer, but leaves the newline on the input-buffer, so the subsequent keyboard.nextLine() thinks there's an empty line there waiting for it.
Related
I'm Adrian and i'm kinda new to programming, would like to learn more and improve. I was asked to do a grade average exercise and i did this , but i'm stuck at making the code so if you type a number instead of a name the code will return from the last mistake the writer did , like it asks for a name and you put "5". In my code gives an error and have to re-run it. Any tips?
import java.util.*;
import java.math.*;
import java.io.*;
class Grades {
public static void main(String[] args) {
int j = 1;
double sum = 0;
double average;
Scanner keyboard = new Scanner(System.in);
System.out.println("Insert Student's Name");
String name = keyboard.next();
System.out.println("Insert Student's Surname");
String surname = keyboard.next();
System.out.println("Student's name: " + name + " " + surname);
System.out.println("How many Grades?");
int nVotes = keyboard.nextInt();
int[] arrayVotes = new int[nVotes];
System.out.println("Now insert all the grades");
for (int i=0; i<arrayVotes.length; i++) {
System.out.println("Insert the grade " + j);
arrayVotes[i] = keyboard.nextInt();
j++;
}
for (int i=0; i<arrayVotes.length; i++) {
sum += arrayVotes[i];
}
average = sum / arrayVotes.length;
System.out.println("Student's grade average is: " + average);
System.out.println("Does he have a good behaviour? Answer with true or false");
boolean behaviourStudent = keyboard.nextBoolean();
average = !behaviourStudent ? Math.floor(average) : Math.ceil(average);
System.out.println("The grade now is: " + average);
keyboard.close();
}
}
At the heart of any solution for this, it requires a loop, and a condition for resetting.
String result = null;
while (result == null) {
//OUT: Prompt for input
String input = keyboard.next();
if (/* input is valid */) {
result = input; //the loop can now end
} else {
//OUT: state the input was invalid somehow
}
//Since this is a loop, it repeats back at the start of the while
}
//When we reach here, result will be a non-null, valid value
I've left determining whether a given input is valid up to your discretions. That said, you may consider learning about methods next, as you can abstract this prompting/verification into a much simpler line of code in doing so (see: the DRY principle)
There are several ways to do it.
But the best way is to use regex to validate the user input.
Have a look at the below code, you can add other validations as well using regex.
import java.util.Scanner;
class Grades {
public static boolean isAlphabetOnly(String str)
{
return (str.matches("^[a-zA-Z]*$"));
}
public static void main(String[] args) {
int j = 1;
double sum = 0;
double average;
Scanner keyboard = new Scanner(System.in);
System.out.println("Insert Student's Name");
String name = keyboard.next();
if(!isAlphabetOnly(name)){
System.out.println("Please enter alfabets only");
return;
}
System.out.println("Insert Student's Surname");
String surname = keyboard.next();
System.out.println("Student's name: " + name + " " + surname);
System.out.println("How many Grades?");
int nVotes = keyboard.nextInt();
int[] arrayVotes = new int[nVotes];
System.out.println("Now insert all the grades");
for (int i=0; i<arrayVotes.length; i++) {
System.out.println("Insert the grade " + j);
arrayVotes[i] = keyboard.nextInt();
j++;
}
for (int i=0; i<arrayVotes.length; i++) {
sum += arrayVotes[i];
}
average = sum / arrayVotes.length;
System.out.println("Student's grade average is: " + average);
System.out.println("Does he have a good behaviour? Answer with true or false");
boolean behaviourStudent = keyboard.nextBoolean();
average = !behaviourStudent ? Math.floor(average) : Math.ceil(average);
System.out.println("The grade now is: " + average);
keyboard.close();
}
}
I am creating a program that takes in employee payroll information and then displays the average and total afterwards. Everything seems to be working correctly except for the fact I cannot get the program to end when I enter the sentinel value of -1 for the hours worked so that the program can display the total and average of the employees. Any help is greatly appreciated.
import java.util.Scanner;
public class PayrollDo
{
public static void main(String[] args)
{
int hoursWorked = 0;
int grossPay = 0;
int empCounter = 0;
int total = 0;
Scanner keyboard = new Scanner(System.in);
do {
total = total + grossPay; // add gross to total
empCounter = empCounter + 1; // incriment counter
System.out.print("Enter hours worked: ");
hoursWorked = keyboard.nextInt();
System.out.print("Enter hourly wage: ");
int hourlyWage = keyboard.nextInt();
//System.out.println("Grosspay is " + (hourlyWage * hoursWorked));
keyboard.nextLine();
System.out.println("Enter employee name ");
String name = keyboard.nextLine();
} while(hoursWorked != -1);
// if user entered at least one employee
if (empCounter != 0) {
// use number with decimal point to calculate average of employees
int average = (int) total / empCounter;
// display total and average (with two digits of precision)
System.out.printf("%nTotal of the %d employees entered is %d%n",
empCounter, total);
System.out.printf("Employee average is " + average);
}
else {
// no employees were entered, so output appropriate message
System.out.println("No employees were entered");
}
}
}
Test soon after entering the value whether it is -1 or not
System.out.print("Enter hours worked: ");
hoursWorked = keyboard.nextInt();
if (hoursWorked == -1) break;
edit
I think you will also have trouble with Integer division http://stackoverflow.com/questions/4685450/why-is-the-result-of-1-3-0
You could restructure your do loop to put the hoursWorked input last (otherwise you have to complete the entries) - and also, add a conditional to reject all entries that cycle, otherwise empCounter is off by one. And I think the total calculation needs reworking too:
do {
System.out.println("Enter employee name ");
String name = keyboard.nextLine();
System.out.print("Enter hourly wage: ");
int hourlyWage = keyboard.nextInt();
System.out.print("Enter hours worked: ");
hoursWorked = keyboard.nextInt();
keyboard.nextLine();
if (hoursWorked != -1) {
total = total + (hourlyWage * hoursWorked); //
empCounter = empCounter + 1; // incriment counter
}
} while(hoursWorked != -1);
In cases like this it can be simpler to have a question like "More Employees? (y/n)" that is used to terminate the loop, using a boolean flag as the while terminator.
I wrote this program to calculate the total number of votes that each person got in an election, and to enter multiple districts. When I try to enter another district the program just prints out the votes received from the first district instead of setting up another poll. What is wrong with it and how do I fix it?
import java.util.Scanner;
public class Election{
public static void main (String[] args){
int votesForPolly = 0; // number of votes for Polly in each precinct
int votesForErnest = 0; // number of votes for Ernest in each precinct
int totalPolly = 0; // running total of votes for Polly
int totalErnest = 0; // running total of votes for Ernest
String response = ""; // answer (y or n) to the "more precincts" question
Scanner scan = new Scanner(System.in);
System.out.println ();
System.out.println ("Election Day Vote Counting Program");
System.out.println ();
// Initializations
// Loop to "process" the votes in each precinct
{
System.out.println ("Enter Votes? Enter Y or N");
response=scan.next().toUpperCase();
if (response.equals("Y")){
response="Yes";
System.out.println ("Enter votes for Polly:");
votesForPolly=scan.nextInt();
totalPolly=totalPolly+ votesForPolly;
System.out.println ("Enter votes for Ernest:");
votesForErnest=scan.nextInt();
totalErnest=totalErnest+ votesForErnest;
System.out.println ("Enter another District? Enter Y or N");
response=scan.next().toUpperCase();
}else{
int count = 0;
while (count == 1){
// Print out the results
}
}
System.out.println ("Total votes for Polly is: " + totalPolly);
System.out.println ("Total votes for Ernest is: " + totalErnest);
}
}
}
Your current looping is broken (because you start with count = 0, therefore while (count == 1) is not entered, I would rewrite it as follows
final String msg = "Enter Votes for District %d?"
+ " Enter Y to continue, N to stop.\n";
// Loop to "process" the votes in each precinct
for (int i = 1;; i++) {
System.out.printf(msg, i);
response = scan.next().toUpperCase();
if (response.startsWith("N")) {
break;
}
System.out.println("Enter votes for Polly: ");
votesForPolly = scan.nextInt();
totalPolly += votesForPolly;
System.out.println("Enter votes for Ernest: ");
votesForErnest = scan.nextInt();
totalErnest += votesForErnest;
}
System.out.printf("Total votes for Polly is: %d\n"
+ totalPolly);
System.out.printf("Total votes for Ernest is: %d\n"
+ totalErnest);
You are not looping through the polling section.
Change
if (response.equals("Y")){
to
while (response.equals("Y")){
and remove the else statement.
I have two programs:
Score.java set to do the following:
read scores from the keyboard and print their average.
The scores will be numeric and may include a decimal part.
For example a score might be 8.73 or some such. Different contests will have different numbers of judges. It will keep asking for and reading in scores until the user types 'done'. The program will then print the total score, the number of scores and the average score. The program will then prompt the user to see if there are any more contestants. If there are begin prompting for scores again. If there are no more then exit the program." I have it set to stop the program when you enter "N", and set to add future entries to the calculation after entering "Y".
import java.util.Scanner;
// This is the Score program
// Written by me
public class Score
{
public static void main(String args[])
{
Scanner game = new Scanner(System.in);
double num = 0.0;
double sum = 0.0;
int cnt = 0;
while (true)
{
System.out.println("Enter as many non-negative integers as you like ");
System.out.println("one at a time and I will find the average");
System.out.println("Enter done to stop entering numbers");
System.out.print("enter number: ");
String ans = game.next();
while (!ans.equals("done"))
{
num = Double.parseDouble(ans);
sum = sum + num;
cnt = cnt + 1;
System.out.print("enter number: ");
ans = game.next();
}
System.out.println(cnt);
System.out.println(sum);
System.out.println("Total Score " + sum + " count scores " + cnt + " avg score " + sum / cnt);
System.out.println("Enter another contestant (Y/N)?");
String str = game.next();
if (!str.equals("Y"))
break;
}
}
}
While the above process works, I cannot get my second program, Olympic.java, to work properly after typing "Y" to add more scores. Instead, it starts a whole new calculation of average instead of adding to the previous calculations:
import java.util.Scanner;
// This is the Olympic program
// Written by me
public class Olympic
{
public static void main(String args[])
{
Scanner game = new Scanner(System.in);
double num = 0.0;
double sum = 0.0;
int cnt = 0;
double highscore = Double.MAX_VALUE;
double lowscore = Double.MIN_VALUE;
while (true)
{
System.out.println("Enter as many non-negative integers as you like ");
System.out.println("one at a time and I will find the average");
System.out.println("Enter done to stop entering numbers");
System.out.print("enter number: ");
String ans = game.next();
lowscore = game.nextDouble();
highscore = game.nextDouble();
while (!ans.equals("done"))
{
num = Double.parseDouble(ans);
sum = (sum + num) - lowscore - highscore;
cnt = cnt + 1;
System.out.print("enter number: ");
if (num > highscore)
{
highscore = num;
}
if (num < lowscore)
{
lowscore = num;
}
ans = game.next();
}
System.out.println("Throwing out low score " + lowscore + " and high score " + highscore);
System.out.println("Total Score " + sum + " count scores " + cnt + " avg score " + sum / cnt);
System.out.println("Enter another contestant (Y/N)?");
String str = game.next();
if (!str.equals("Y"))
break;
}
}
}
So I did a really quick test
public static void main(String[] args) {
Scanner game = new Scanner(System.in);
while (true) {
System.out.println("Enter another contestant (Y/N)?");
String str = game.next();
if (!str.equalsIgnoreCase("Y")) {
break;
}
}
System.out.println("I'm free");
}
And this will exit fine.
As to your second problem. I think your logic is a little skewed. You could try something like...
Scanner game = new Scanner(System.in);
double num = 0;
double sum = 0;
int cnt = 0;
while (true) {
System.out.println("Enter as many non-negative integers as you like ");
System.out.println("one at a time and I will find the average");
System.out.println("Enter done to stop entering numbers");
double lowscore = Double.MAX_VALUE;
double highscore = 0;
System.out.print("enter number: ");
String ans = game.next();
while (!ans.equals("done")) {
num = Double.parseDouble(ans);
lowscore = Math.min(lowscore, num);
highscore = Math.max(highscore, num);
sum += num;
cnt++;
System.out.print("enter number: ");
if (num > highscore) {
highscore = num;
}
if (num < lowscore) {
lowscore = num;
}
ans = game.next();
}
sum -= lowscore;
sum -= highscore;
System.out.println("Throwing out low score " + lowscore + " and high score " + highscore);
System.out.println("Total Score " + sum + " count scores " + cnt + " avg score " + sum / cnt);
System.out.println("Enter another contestant (Y/N)?");
String str = game.next();
if (!str.equalsIgnoreCase("Y")) {
break;
}
}
This will output...
Enter as many non-negative integers as you like
one at a time and I will find the average
Enter done to stop entering numbers
enter number: 1
enter number: 2
enter number: 3
enter number: 4
enter number: 5
enter number: 6
enter number: 7
enter number: 8
enter number: 9
enter number: 10
enter number: done
Throwing out low score 1.0 and high score 10.0
Total Score 44.0 count scores 10 avg score 4.4
Enter another contestant (Y/N)?
y
Enter as many non-negative integers as you like
one at a time and I will find the average
Enter done to stop entering numbers
enter number: 1
enter number: 12
enter number: 13
enter number: 14
enter number: 15
enter number: 16
enter number: 17
enter number: 18
enter number: 19
enter number: 20
enter number: done
Throwing out low score 1.0 and high score 20.0
Total Score 168.0 count scores 20 avg score 8.4
Enter another contestant (Y/N)?
n
As to your exception. When using Scanner.nextDouble, it will throw an exception if the input is not parsable as a double. You will need to deal with this situation as you see fit...
Please help with my assignment. Here is the question:
Create a separate test driver class
called TestEmployeePayroll that will
test the EmployeePayroll class by
performing the following:
Prompt the user to enter the
employees’ ID number, First name, Last
name, Pay Category and Hours worked
(one at a time).
The user entry for employees ID
number must be exactly 5 digits long.
The user entry for Category must only
be accepted if it is in the range 1
to 4.
The user entry for Hours worked
must only be accepted if it is the
range 1 to 80.
This is what I did till now:
import java.util.Scanner;
public class TestEmployeePayRoll {
public static void main(String[] args){
EmployeePayRoll obj1 = new EmployeePayRoll();
Scanner input = new Scanner(System.in);
System.out.println("Enter the Employee ID number: "+ " ");
String EmployeeID = input.nextLine();
//How to check the range here if int is 5 digits long or not ?
System.out.println("Enter the first Name: "+ " ");
String FirstName = input.nextLine();
System.out.println("Enter Last Name: "+ " ");
String LastName = input.nextLine();
System.out.println("Enter the Pay Category: "+ " ");
double PayCategory = input.nextDouble();
System.out.println("Enter the number of hours worked: "+ " ");
double HoursWorked = input.nextDouble();
}
}
You will probably want to use Integer.parseInt().
You can count the length of a String and then convert it to number, Oli Charlesworth told you how to convert it, or you can measure the number. It depends on what you want. Is 012345 a valid ID? It's a 6 char String but it is less than the biggest 5 digits number.
I think you almost got it...
import java.util.Scanner;
public class TestEmployeePayRoll {
public static void main(String[] args){
// ... get the values, as you are doing already
// validate input
int employeeIdAsInteger = validateAndConvertEmployeeId(EmployeeId);
int payCategoryAsInteger = validateAndConvertPayCategory(PayCategory);
// ... and so on
}
private int validateAndConvertEmployeeId(String employeeId) {
// The user entry for employees ID number must be exactly 5 digits long.
if (employeeId == null || employeeId.trim().length() != 5) {
throw new IllegalArgumentException("employee id must be exactly 5 digits long");
}
// will throw an exception if not a number...
return Integer.parseInt(employeeId);
}
// ...
}
Depending on your objectives & constraints, you could look into the Pattern class and use a regular expression.
You can check for conditions like this.
import java.util.Scanner;
public class TestEmployeePayRoll {
public static void main(String[] args) {
TestEmployeePayRoll obj1 = new TestEmployeePayRoll();
Scanner input = new Scanner(System.in);
System.out.println("Enter the Employee ID number: " + " ");
String EmployeeID = input.nextLine();
if (EmployeeID.trim().length() != 5) {
System.out.println("--- Enter valid Employee ID number ---");
}
System.out.println("Enter the first Name: " + " ");
String FirstName = input.nextLine();
System.out.println("Enter Last Name: " + " ");
String LastName = input.nextLine();
System.out.println("Enter the Pay Category: " + " ");
double PayCategory = input.nextDouble();
Double pay = new Double(PayCategory);
if (pay.isNaN()) {
System.out.println("***** Enter a valid Pay Category *****");
}
if (!(PayCategory >= 0 && PayCategory <= 5)) {
System.out.println(" --- PayCategory must be between 0 and 5");
}
System.out.println("Enter the number of hours worked: " + " ");
double HoursWorked = input.nextDouble();
Double hours = new Double(HoursWorked);
if (hours.isNaN()) {
System.out.println("--- Enter a valid hours value ----");
} else {
if (!(HoursWorked >= 1 && HoursWorked <= 80)) {
System.out.println("--- Enter value between 1 and 80 ---");
}
}
}
}