public class AppointmentSchedule {
private static final int NUM_APPOINTMENTS = 6;
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] scheduled = new String[NUM_APPOINTMENTS];
Scanner consoleScanner = new Scanner(System.in);
int i;
String name;
for (int z = 0; z < NUM_APPOINTMENTS; z++) {
scheduled[z] = "";
}
System.out.println("To schedule an appointment, Please enter a time between 1PM to 6PM");
do {
i = consoleScanner.nextInt();
try {
if (i >= 1 && i <= 6) {
try {
if (scheduled[i] == "") {
System.out.println("Please enter your name.");
name = consoleScanner.next();
scheduled[i] = name;
System.out.println("Thank you " + name
+ ", you have been scheduled for " + i
+ " PM.\n");
System.out
.println("To schedule an appointment, Please enter a time between 1PM to 6PM");
} else {
throw new TimeInUseException();
}
} catch (TimeInUseException ex1) {
System.out.println(ex1.getMessage());
}
} else
throw new InvalidTimeException();
} catch (InvalidTimeException ex) {
System.out.println(ex.getMessage());
}
} while ();
consoleScanner.close();
}
}
What are some techniques to end the do while loop after scheduled[i] is filled up with 6 elements?
Would it look like: while (scheduled[z] != 6)?
Do this while(i<=5); this will let your loop run even when i=6 here i is the variable you keep incrementing
Just keep track of how many inputs the user has made. This can be done by declaring
int count = 0;
before the do...while loop and incrementing it from the body of the inner if:
if (scheduled[i - 1] == "") {
System.out.println("Please enter your name.");
name = consoleScanner.next();
scheduled[i - 1] = name;
System.out.println("Thank you " + name
+ ", you have been scheduled for " + i
+ " PM.\n");
count++; /* Note this */
System.out.println("To schedule an appointment, Please enter a time between 1PM to 6PM");
}
and finally, change the condition to
} while (count < 6);
Related
I have a condition where if the user inputs a negative number or a number which is more than 100, or a string, an error message should be printed "That wasn't a valid percentage, I need a number between 0-100. Try again." and ask the user to reenter a valid number. and if the user decided to just enter, all the input should be calculated and printed the average amount.
public static void main(String[ ] args) {
int count = 0; //count to stop loop
double[ ] aGrade = new double[SIZE];
String input = new String("");
Scanner scan = new Scanner(System.in);
double total = 0;
int gTotal = aGrade.length;
boolean exit = false;
while ((count < SIZE) && (!exit)) {
System.out.print("Enter number " + (count + 1) + ": " + "\n");
try {
input = scan.nextLine();
if (Double.parseDouble(input) > 0 && Double.parseDouble(input) < 100) {
aGrade[count] = Double.parseDouble(input); //put into the array
count++; //only increment count if success
} else
System.out.println("That wasn't a valid percentage,"
+ " I need a number between 0-100. Try again.");
} catch (NumberFormatException nfe) {
exit = true; //exit loop
}
}
System.out.println("number of grades entered: " + count + "\n");
for (int i = 0; i < count; i++) {
// print entered grade
System.out.println("grade " + (i + 1) + ": " + aGrade[i]);
}
for (int i = 0; i < count; i++) {
total += aGrade[i];
}
// calculate and print the average
System.out.println("\n" + "Average grade: " + total /count);
But when I run my code, if I input letters, it won't allow the user to reinput value but prints whatever is calculated. I think it is in my if-else statement, but I am not sure how
When we try to convert String to Double it will throw java.lang.NumberFormatException. So whenever you enter String or char at that time instead of else it will go to catch block. As per your code else block only executed when user enter negative number or grater then 100 number.
I updated your code. Please review it.
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
int count = 0; // count to stop loop
double[] aGrade = new double[3];
String input = new String("");
Scanner scan = new Scanner(System.in);
double total = 0;
int gTotal = aGrade.length;
boolean exit = false;
while ((count < 3) && (!exit)) {
System.out.print("Enter number " + (count + 1) + ": " + "\n");
try {
input = scan.nextLine();
if (Double.parseDouble(input) > 0 && Double.parseDouble(input) < 100) {
aGrade[count] = Double.parseDouble(input); // put into the array
count++; // only increment count if success
} else
System.out
.println("That wasn't a valid percentage," + " I need a number between 0-100. Try again.");
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
exit = true; // exit loop
}
}
if (!exit) {
System.out.println("number of grades entered: " + count + "\n");
for (int i = 0; i < count; i++) {
// print entered grade
System.out.println("grade " + (i + 1) + ": " + aGrade[i]);
}
for (int i = 0; i < count; i++) {
total += aGrade[i];
}
// calculate and print the average
System.out.println("\n" + "Average grade: " + total / count);
}else {
System.out
.println("That wasn't a valid percentage," + " I need a number between 0-100. Try again.");
}
}
}
If you type letter as an input, you will never end up in your else part of the if statement since code inside if throws an exception and you are then inside catch part. Also, you wrote inside catch part, when NumberFormatException happens(when you enter letter instead of number), set exit to true and that is the reason why program don't let you type again after you input letter. Fix those things and it will work. Also, take a look at how to debug your program, learn that skill, it will help you to solve this kind of problems in the future.
Try something like this:
boolean ok = false;
try {
input = scan.nextLine();
if ("".equals(input)) {
ok = true;
exit = true;
} else if (Double.parseDouble(input) >= 0 && Double.parseDouble(input) <= 100) {
aGrade[count] = Double.parseDouble(input); //put into the array
count++; //only increment count if success
ok = true;
}
} catch (NumberFormatException nfe) {
// nothing
}
if (!ok) {
System.out.println("That wasn't a valid percentage,"
+ " I need a number between 0-100. Try again.");
}
Can anyone help?
Choice 2 isn't working. It is suppose to display the employee ID when the user inputs the employee Name, but when the user enters the name nothing prints. The code has no errors.
public static void main(String[] args) {
int[] emplID={ 42577, 38611, 32051, 28627, 42061, 79451 };//employee ID
int ID = employeeID(emplID);
String[] emplNames= { "Bruce Wayne", "Barry Allen", "Hal Jordan", "Dinah Lance", "Oliver Queen", "Tineil Charles" };// Employee Names
search(emplNames, emplID);
//methods called from main
}
public static int employeeID(int [] emplID) {
//check ID length
for(int i=0; i< emplID.length; i++) {
if((emplID[i] > 10000)&&(emplID[i] < 99999)) {
System.out.print(emplID[i] + " - Valid ID length\n");
}
else {
System.out.println(emplID[i] + " - Invalid ID! ID must be Five digits!\n");
}//end of check length
//check if ID is prime
boolean isPrime = true;
for (int j = 2; j < emplID[i]; j++) {
if (emplID[i] % j == 0) {
System.out.println(emplID[i] + " - not prime");
isPrime = false;
break;
}
}
if(isPrime) System.out.println(emplID[i] + " - valid prime");//end of check prime
}//end of employeeID method
return 0;
}// end of ID checker
// search employee data
public static void search(String[] emplNames, int[]emplID) {
Scanner scan= new Scanner(System.in);
//Menu Choice
System.out.println("Please choose 1 to enter Employee ID or 2 to enter Employee Name:" );
int num = scan.nextInt();//input choice
// Choice 1 to enter ID to display name
if (num == 1) {
System.out.println("Please enter Employee ID:");
int searchID= scan.nextInt();
for(int ID = 0; ID < emplID.length; ID++) {
if (searchID == (emplID[ID])){
System.out.println("Name: "+ emplNames[ID]);
}
}
}
// Choice 2 to enter name to display ID
else if(num == 2) {
System.out.println("Please enter Employee Name");
String searchName= scan.next();
for(int ID = 0; ID< emplID.length; ID++){
if ((searchName.equals(emplNames[ID]))){
System.out.println("ID: " + emplID[ID]);
}
}
}
else
System.out.println("Employee Not Found");
}
}
I copied and pasted your code and ran it on my machine. Yes, choice 2 was not working for me either.
Before reading your code completely my gut feeling was that the cause of failure was in using the Scanner class to get the name of the employee. I have had similar issues in the past and the best move is to learn to use the InputStreamReader and BufferedStreamReader objects.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
1: I didn't do anything to your main()
public static void main(String[] args) {
int[] emplID={ 42577, 38611, 32051, 28627, 42061, 79451 };//employee ID
int ID = employeeID(emplID);
String[] emplNames= { "Bruce Wayne", "Barry Allen", "Hal Jordan", "Dinah Lance", "Oliver Queen", "Tineil Charles" };// Employee Names
search(emplNames, emplID);
}
2: I didn't do anything to your employeeID() function
public static int employeeID(int [] emplID) {
//check ID length
for(int i=0; i< emplID.length; i++) {
if((emplID[i] > 10000)&&(emplID[i] < 99999)) {
System.out.print(emplID[i] + " - Valid ID length\n");
}
else {
System.out.println(emplID[i] + " - Invalid ID! ID must be Five digits!\n");
}//end of check length
//check if ID is prime
boolean isPrime = true;
for (int j = 2; j < emplID[i]; j++) {
if (emplID[i] % j == 0) {
System.out.println(emplID[i] + " - not prime");
isPrime = false;
break;
}
}
if(isPrime) System.out.println(emplID[i] + " - valid prime");//end of check prime
}//end of employeeID method
return 0;
}// end of ID checker
3: It's in your search() method where I first created the InputStreamReader and the BufferedReader:
public static void search(String[] emplNames, int[]emplID) {
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader buff = new BufferedReader(in);
//Menu Choice
System.out.println("Please choose 1 to enter Employee ID or 2 to enter Employee Name:" );
int num = 0;
try {
num = Integer.parseInt(buff.readLine());
} catch (Exception e) {
e.printStackTrace();
}
4: Since choice 1 works fine, all I did was change your for loop to a for-each loop to make it easier to read.
// Choice 1 to enter ID to display name
if (num == 1) {
System.out.println("Please enter Employee ID:");
int searchID = 0;
try {
searchID = buff.read();
} catch (Exception e) {
e.printStackTrace();
}
for (int i : emplID) {
if (searchID == i) {
System.out.println("Name: " + emplNames[i]);
}
}
5: Here is what I did to make your 2nd Option work. Again, get the String from user via BufferedReader object's readLine() method. Then, it was just letting your for-loop searching for a match. That's it. Afterward, I ran the program and tested it for all the names you had above, works fine.
} else if (num == 2) {
System.out.println("Please enter Employee Name");
String searchName = "";
try {
searchName = buff.readLine();
} catch(Exception e) {
e.printStackTrace();
}
for(int ID = 0; ID< emplID.length; ID++){
if ((searchName.equals(emplNames[ID]))){
System.out.println("ID: " + emplID[ID]);
}
}
} else {
System.out.println("Employee Not Found");
}
}
}
6: Yeah, Scanner has an issue where it either doesn't read the entire line or you need to flush the stream before getting the input. It caused a lot of problems for me in a bunch of easy programs. Then I switched to using the InputStreamReader and BufferedStreamReader combo. Just wrap them in try-catch blocks, and you're fine. Look into it, it will the behavior of your code and your life a lot easier.
7: I hope this was helpful.
I need help coding a set of statements of data validation that checks if a user entry is within a range of 0 and 100, and anything the user types that ISNT a non-decimal integer between 1 and 100 should display an error message. Also I need a way to code how I can get a "goodbye" output to only display if the user enters "n" not "n" and "y." N meaning no and y meaning yes.
Heres my code.
import java.util.Scanner;
public class GuessingGameCalc {
private static void displayWelcomeMessage(int max) {
System.out.println("Welome to the Java Guessing Game!");
System.out.println(" ");
System.out.println("I'm thinking of a number between 1 and" + " " + max + " " + "let's see if you guess what it is!");
System.out.println(" ");
}
public static int calculateRandomValue(int max) {
double value = (int) (Math.random() * max + 1);
int number = (int) value;
number++;
return number;
}
public static void validateTheData(int count) {
if( count < 3) {
System.out.println("Good job!");
} else if (count < 7) {
System.out.println("Need more practice.");
} else{
System.out.println("Need way more practice.");
}
}
public static void main(String[] args) {
final int max = 100;
String prompt = "y";
displayWelcomeMessage(max);
int unit = calculateRandomValue(max);
Scanner sc = new Scanner(System.in);
int counter = 1;
while (prompt.equalsIgnoreCase("y")) {
while (true) {
System.out.println("Please enter a number.");
int userEntry = sc.nextInt();
if (userEntry < 1 || userEntry > max) {
System.out.println("Invalid guess! Guess again!");
continue;
}
if (userEntry < unit) {
if ( (unit - userEntry) > 10 ) {
System.out.println("Way Too low! Guess higher!");
} else {
System.out.println("Too low! Guess higher!");
}
} else if (userEntry > unit) {
if( (userEntry - unit) > 10 ){
System.out.println("Way Too high! Guess lower!");
} else {
System.out.println("Too high! Guess lower!");
}
} else {
System.out.println("Congratulations! You guessed it in" + " " + counter + " " + "tries!\n");
validateTheData(counter);
break;
}
counter++;
}
System.out.println("Would you like to try again? Yes or No?");
prompt = sc.next();
System.out.println("Goodbye!");
}
}
}
Instead of using .nextInt() rather use .nextLine(), which returns a String and then parse it to an int and catch the NumberFormatException
So basically you'll have this structure:
try {
int userEntry = Integer.parseInt(sc.nextLine());
...
} catch (NumberFormatException nfe) {
System.out.println("Please enter a valid number.");
}
Oh, just a comment on the rest of your code. You don't really need two while loops, one will be more than sufficient.
I have encountered a problem: I need to be able to filewrite after I have added to the array (dock) and removed from the array (undock) on the fly. But I do not know where to put the flush() and close(). I get errors when I but it after the write function wherever I put them because they have already closed the filewriter. Can you help?
try {
portLog.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
portLog.close();
} catch (IOException e) {
e.printStackTrace();
}
Here is my code:
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
static Scanner scan = new Scanner(System.in);
private static Ship[] dock1 = new Ship[10];
private static Ship[] waitingList = new Ship[10];
static FileWriter portLog;
static DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
//get current date time with Date()
static Date date = new Date();
static {
try {
portLog = new FileWriter("\\Users\\Smith\\Desktop\\PortLog.txt", true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
menu();
}
public static void menu() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("Choose an option: 1-3");
System.out.println("1. Dock");
System.out.println("2. Undock");
System.out.println("3. Status");
int menu = scan.nextInt();
switch (menu) {
case 1:
System.out.println("1. Dock");
dock();
break;
case 2:
System.out.println("2. Undock");
undock();
break;
case 3:
System.out.println("3. Status");
printDock();
printWaitingList();
break;
case 4:
System.out.println("4. Exit");
System.exit(0);
default:
System.out.println("No such option");
break;
}
}
}
public static void dock() {
System.out.println("Enter ship's name: ");
String name = scan.nextLine();
System.out.println("Enter ship's size: ");
String size = scan.nextLine();
System.out.println("Enter the ships dock:");
//Check if the dock number is valid
int i = Integer.valueOf(scan.nextLine());
if (i >= 0 && i < 10 && dock1[i] == null) {
int c = 0;
int co = 0;
int sco = 0;
for (int j = 0; j < dock1.length; j++) {
if (dock1[j] != null && dock1[j].getShipSize().equals("Cargo")) {
c++;
}
if (dock1[j] != null && dock1[j].getShipSize().equals("Container")) {
co++;
}
if (dock1[j] != null && dock1[j].getShipSize().equals("Super-Container")) {
sco++;
}
}
if (c < 10 && co < 5 && sco < 2) {
//Add ship to the dock
dock1[i] = new Ship(name, size);
System.out.println("Enough space you can dock");
System.out.println("Ship has been docked");
try {
portLog.write("\n" + " Docked: " + dock1[i].getShipName() + " Size: " + dock1[i].getShipSize() + " at " + dateFormat.format(date));
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("You cannot dock");
waitingList(name, size);
}
} else {
System.out.println("Couldn't dock");
waitingList(name, size);
}
}
public static void undock() {
System.out.println("Status of ships: ");
printDock();
System.out.println("Enter ship's name to undock: ");
String name = scan.nextLine();
for (int i = 0; i < dock1.length; i++) {
if (dock1[i] != null && dock1[i].getShipName().equals(name)) {
try {
portLog.write("\n" + "Undocked: " + dock1[i].getShipName() + " Size: " + dock1[i].getShipSize() + " at " + dateFormat.format(date));
} catch (IOException e) {
e.printStackTrace();
}
dock1[i] = null;
System.out.println("Ship removed");
/// HERE CHECK IF SHIP IN DOCK
for (int j = 0; j < waitingList.length; j++) {
if (dock1[i] == null && waitingList[j] != null) {
// Add ship to the dock
dock1[i] = new Ship(waitingList[j].getShipName(), waitingList[j].getShipSize());
System.out.println("Move ship from waiting list to dock 1");
waitingList[j] = null;
return;
} else {
return;
}
}
} else {
}
}
System.out.println("Ship not found");
}
public static void waitingList(String name, String size) {
System.out.println("Dock 1 is full, ship will try to be added to Waiting List");
for (int i = 0; i < waitingList.length; i++) {
if (waitingList[i] == null) {
//Add ship to the dock
waitingList[i] = new Ship(name, size);
System.out.println("Enough space added to waiting list");
return;
} else {
}
}
System.out.println("No space on waiting list, ship turned away.");
}
public static void printDock() {
System.out.println("Docks:");
for (int i = 0; i < dock1.length; i++) {
if (dock1[i] == null) {
System.out.println("Dock " + i + " is empty");
} else {
System.out.println("Dock " + i + ": " + dock1[i].getShipName() + " " + dock1[i].getShipSize());
}
}
}
private static void printWaitingList() {
System.out.println("Waiting List:");
for (int i = 0; i < waitingList.length; i++) {
if (waitingList[i] == null) {
System.out.println("Dock " + i + " is empty");
} else {
System.out.println("Dock " + i + ": " + waitingList[i].getShipName() + " " + waitingList[i].getShipSize());
}
}
}
}
That is the thing when you are new to Java, and first start using all static variables within a single class. That is good for the first steps, and getting a hello world printed, or some simple calculations.
But then this approach quickly gets into your way. You see, in the "real" world of OOP, such code is much more of an anti-pattern.
Meaning: that is where you should starting thinking of creating classes of your own. A class has a distinct purpose, like modelling a Ship, or maybe a Dock. Then you add think about the properties that belong into such classes (and for sure: these fields are not static) then.
In that sense, the real answer here is that you "fully" step back and start thinking about better ways to organize the functionalities that you intend to create. As said, in your case, that boils down to define proper Ship/Dock classes. That will then allow you to abstract lower level details, such as "some stuff is stored in files". Because then you can have a DockPersistenceService class for example. Which you pass a list of Dock objects, to somehow persist them. Or that reads a list of Dock objects from a file.
As a general principle, it's a good idea for a resource like this to have a well-defined lifetime. That will typically mean that it's not static. #GhostCat is right that you should really consider a more robust approach, but as a starting point, I'd suggest this.
public static void menu() {
Scanner scan = new Scanner(System.in);
boolean keepProcessing = true; // use this to control the loop, don't call System.exit!
// use try-with-resources to control resource lifetime
try (FileWriter portLog = new FileWriter("\\Users\\Smith\\Desktop\\PortLog.txt", true)) {
while (keepProcessing) {
int choice = scan.nextInt();
switch (choice) {
case 1:
System.out.println("1. Dock");
dock(portLog);
break;
// Other cases skipped for brevity
case 4:
keepProcessing = false;
break;
// Other cases skipped for brevity
}
}
}
}
Then, have your other methods accept the portLog as a parameter.
public static void dock(FileWriter portLog) {
// ...
}
With this setup, the menu method will open the portLog file when it starts up, and close it when the method is finished. It also makes it clearer that the dock, undock, etc. methods require the use of the FileWriter object.
I'm currently working on some exercises given to me by my teacher. These are for the holidays so I won't be able to ask for help there.
I have this piece of code which creates a multiplication table from an integer defined by the user, ranging from a minimum and maximum also defined by the user.
Before setting any of my variables to the next integer in my Scanner, I do a check to see if the Scanner actually has an integer. This works fine but I don't want it to print out the error message a billion times.
Any tips/tricks or other special ways of getting around this?
public class MultiplicationTable
{
private int intervalMin;
private int intervalMax;
private int multiplier;
private int result;
private Scanner sc;
public MultiplicationTable()
{
multiplier = 0;
intervalMin = 0;
sc = new Scanner(System.in);
while (multiplier == 0)
{
System.out.println("Please enter the integer you wish to show the table for");
if (sc.hasNextInt())
{
multiplier = sc.nextInt();
}
else
{
System.out.println("Input is not an integer\n");
}
}
while (intervalMin == 0)
{
System.out.println("\nPlease enter the integer defining the start of the table");
if (sc.hasNextInt())
{
intervalMin = sc.nextInt();
}
else
{
System.out.println("Input is 0 or not an integer\n");
}
}
while (intervalMax == 0)
{
System.out.println("\nPlease enter the integer defining the end of the table");
if (sc.hasNextInt())
{
int i = sc.nextInt();
if (i > intervalMin)
{
intervalMax = i;
}
else
{
System.out.println("\nEnd integer must be greater than start integer");
}
}
else
{
System.out.println("Input is 0 or not an integer");
}
}
System.out.println("\nTable for integer " + multiplier + " from " + intervalMin + " to " + intervalMax + "\n");
for (int i = intervalMin; i <= intervalMax; i++)
{
result = i * multiplier;
System.out.println(i + " * " + multiplier + " = " + result);
}
}
}
You didn't consume what user entered into the scanner buffer, that's why sc.hasNextInt() keeps getting executed without waiting for the next user input.
The solution is to add sc.nextLine() after the if condition.
For example:
boolean gotInteger = false;
while (!gotInteger) {
System.out.println("Please enter the integer you wish to show the table for");
if (sc.hasNextInt()) {
multiplier = sc.nextInt();
gotInteger = true;
} else {
System.out.println("Input is not an integer\n");
}
sc.nextLine();
}
Pleas try this, just wrap all your code inside try catch:
try {
while (intervalMax == 0) {
System . out . println("\nPlease enter the integer defining the end of the table");
if (sc . hasNextInt()) {
int i = sc . nextInt();
if (i > intervalMin) {
intervalMax = i;
} else {
throw new Exception("\nEnd integer must be greater than start integer");
}
}
}
} catch (Exception e) {
System . out . println(e . getMessage());
}