Validate integer - java

This is a program that allows the user to build a high school schedule.
I would like to validate an integer as a high school class number in my String method. Here's the name of my method with the parameters.
public static String addClass(String name, String day, String momentOfDay, int group){
The user has to put an integer as the value of a school class number. The number has to start with a specific number according to the day of class. Here's a table that explains the validation wanted
Day of Class | Valid Group
Monday | The first number of the group must start with 1 ( example 10, 14...)
Tuesday | The first number of the group must start with 2 ( example 20, 22...) ______________________________________________________________________________
Wednesday | The first number of the group must start with 3 ( example 30, 31...) ______________________________________________________________________________
Thursday | The first number of the group must start with 4 ( example 40, 31...) ______________________________________________________________________________
Friday | The first number of the group must start with 5 ( example 50, 56...)
Here's what the output should look like ( the terms in bold are the entered values by the user ) :
**********************
ADD CLASS TO SCHEDULE
**********************
Name of class : **INF1120**
Day of class : **Monday**
Moment of the day of the class : **PM**
Group of class : **12**
I'm using the scanner to allow the user to enter the wanted integer.
I completed the name of class, day and moment of the day part.
However, I'm having a hard time to validate the first number of the group integer according to the days in the table. Here's my code :
import java.util.Scanner;
public class schedule {
public static String addClass(String name, String day, String momentOfDay, int group) {
Scanner keyboard = new Scanner(System.in);
System.out.print("day of class: ");
day = keyboard.nextLine();
if( day != "monday" || day != "tuesday" || day != "wednesday"
|| day != "thursday" || day != "friday" ) {
System.out.print("Error, the day has to be either : monday, tuesday, wednesday, thursday, or friday...");
}
else if(day = "monday" || day = "tuesday" || day = "wednesday"
|| day = "thursday" || day = "friday" ) {
return day;
}
System.out.print("Moment of day: ");
momentOfDay = keyboard.nextLine();
if(momentOfDay != "am" || momentOfDay != "pm" || momentOfDay != "night") {
System.out.print("Error, the moment of the day has to be : am, pm, or evening...");
}
else if(momentOfDay == "am" || momentOfDay == "pm" || momentOfDay == "evening") {
return momentOfDay;
}
System.out.print("Class group");
group = keyboard.nextInt();
while(day == "monday" || day == "tuesday" || day == "wednesday"
|| day == "thursday" || day == "friday"){
if (String.valueOf(Math.abs(int(group)).charAt(0) == 1){
return group;
}
else {
System.out.print("Error, group number is invalid");
}
}
}
}
However, it is not compiling because the return value cannot be an int which is required. Here's the error.
Type mismatch: cannot convert from int to String
It is asking me to either change the return type to int or change the type of group to String.
Should I change the type of group in the parameter ? What did I do wrong ?
I tried to research the methods in this link but can't seem to figure it out.

When I copied the code of class schedule that you posted, I got a compilation error for this line:
if (String.valueOf(Math.abs(int(group)).charAt(0) == 1){
The int should be removed. group is a parameter of method addClass() and it is an int. So the line of code should be:
if (String.valueOf(Math.abs(group)).charAt(0) == 1){
After correcting that line, the line following it causes a compilation error. That line is:
return group;
Method addClass() is declared to return a String but group is an int. So that line should be changed to:
return String.valueOf(group);
After correcting that line of code, I got yet another compilation error, namely that the method does not return a value. This is the while loop in method addClass():
while (day == "monday" || day == "tuesday" || day == "wednesday" || day == "thursday"
|| day == "friday") {
If day is "sunday", the loop is terminated. There needs to be a return statement after that while loop.
But even after fixing all the compilation errors, your code will not work due to logic errors. I just showed you one of those errors in the while loop. Similarly this if statement will not do what you want.
if (day != "monday" || day != "tuesday" || day != "wednesday" || day != "thursday"
|| day != "friday")
Besides that fact that you need to use method equals() to check if two strings are equal, if day is "tuesday", then the first condition, namely day != "monday" is true. If you want to ensure that the user enters a valid day, then you need the following:
if ("monday".equals(day) ||
"tuesday".equals(day) ||
"wednesday".equals(day) ||
"thursday".equals(day) ||
"friday".equals(day)) {
return day;
}
else {
System.out.print(
"Error, the day has to be either : monday, tuesday, wednesday, thursday, or friday...");
}
If day and momentOfDay and group are all parameters of method addClass(), why do you ask the user to enter these values inside method addClass() ? Also the other method parameter, name, is never used in the method.
I think you need to create three, separate methods. One to get the day from the user, another to get the momentOfDay and yet another to get the group.
I suggest you read the book Java by Comparison by Simon Harrer, Jörg Lenhard, Linus Dietz

Related

I'm confused on getters and returns in classes?

I've been teaching myself coding, and getters and return values, and how to call upon them in the main program. To give it a go, I tried to write a program to calculate the cost of long distance calls, but it crashes right when I run it, and I know it has something to do with the class.
Fair warning, my time is a bit weird for calculating AM/PM but I did my best.
I think it has to be something with calling upon the calculations in my main code-- specifically the String weekday = call1.calculateweekday(); and int time = call1.calculatetime(); , but I'm very new to programming and I am very much just starting out and learning these terms and uses, so I've no idea what. I just know, when i move these two lines around my main program, it breaks at that point.
package practice;
import java.util.Scanner;
class Call {
String weekdayinput;
String weekday;
int hour;
String ampm;
int time;
int calculatetime() {
if (ampm.equals("pm") || ampm.equals("PM") || ampm.equals("Pm")) {
time = hour + 1200;
} else if (ampm.equals("am") || ampm.equals("AM") || ampm.equals("Am")) {
time = hour;
}
else {
System.out.println("You entered something either time or AM/PM incorrectly.");
}
return time;
}
String calculateweekday() {
if (weekdayinput.equals("mo") || weekdayinput.equals("Mo") || weekdayinput.equals("MO")) {
weekday = "Monday";
}
else if (weekdayinput.equals("tu") || weekdayinput.equals("Tu") || weekdayinput.equals("TU")) {
weekday = "Tuesday";
}
else if (weekdayinput.equals("we") || weekdayinput.equals("We") || weekdayinput.equals("WE")) {
weekday = "Wednesday";
}
else if (weekdayinput.equals("th") || weekdayinput.equals("Th") || weekdayinput.equals("TH")) {
weekday = "Thursday";
}
else if (weekdayinput.equals("fr") || weekdayinput.equals("Fr") || weekdayinput.equals("FR")) {
weekday = "Friday";
}
else if (weekdayinput.equals("sa") || weekdayinput.equals("Sa") || weekdayinput.equals("SA")) {
weekday = "Saturday";
}
else if (weekdayinput.equals("su") || weekdayinput.equals("Su") || weekdayinput.equals("SU")) {
weekday = "Sunday";
}
else {
System.out.println("You entered your weekday incorrectly.");
}
return weekday;
}
}
public class GettersandREturns {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
Call call1 = new Call();
String weekday = call1.calculateweekday();
int time = call1.calculatetime();
System.out.println("To calculate the cost per minute of your long-distance call, we'll need some information.");
System.out.println(
"What hour are you planning on making the call. Minutes aren't necessary. Please only enter the hour number. (ex. 8)");
call1.hour = input.nextInt();
input.hasNextLine();
System.out.println("Is the call taking place AM or PM?");
call1.ampm = input.nextLine();
input.hasNextLine();
System.out.println("And what day of the week is that? Please enter weekday with only first two letters. (ex. Fr");
call1.weekdayinput = input.nextLine();
if (time >= 8 && time <= 11 && !weekday.equals("Saturday") && !weekday.equals("Sunday")
|| time >= 1212 && time <= 1206 && !weekday.equals("Saturday") && !weekday.equals("Sunday"))
{
System.out.println("Your call will charge $4.50 a minute.");
}
else if (time == 12 && !weekday.equals("Saturday") && !weekday.equals("Sunday")
|| time >= 1 && time < 8 && !weekday.equals("Saturday") && !weekday.equals("Sunday")
|| time > 1206 && time <= 1211 && !weekday.equals("Saturday") && !weekday.equals("Sunday")) {
System.out.println("Your call will charge $4.00 a minute.");
}
else if (weekday.equals("Saturday") || weekday.equals("Sunday")){
System.out.println("Your call will charge $2.25 a minute.");
}
else {
System.out.println("You must have entered something wrong!");
}
}
}
So the idea was any call started between 8:00 Am and 6:00 PM, Monday through Friday, is billed at a rate of 4.50 per minute. Any call starting before 8:00 AM or after 6:00 PM, Monday through Friday, is billed at a rate
of 4.00 per minute. Finally, any call started on a Saturday or Sunday is charged at a rate of 2.25 per minute.
But when i run this program I get Exception in thread "main" java.lang.NullPointerException
at practice.Call.calculateweekday(GettersandREturns.java:32)
at practice.GettersandREturns.main(GettersandREturns.java:82)
Any help would be greatly appreciated. Learning is hard.
In your main function you are creating a new call and calling the functions of the call.
Call call1 = new Call();
String weekday = call1.calculateweekday();
int time = call1.calculatetime();
And at this Points you get the error, if you look at the Call class which got the following variables
String weekdayinput;
String weekday;
int hour;
String ampm;
int time;
You see that These variables aren't initialized at the beginning, for int the Default value is 0 and for a String the Defaultvalue is null (you will Encounter nullpointerexceptions sometimes when you are programming). Having a value of null not forbidden as Long as you dont try to Access this variable and that is what your functions do.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
will be the error which
if (ampm.equals("pm") || ampm.equals("PM") || ampm.equals("Pm"))
will throw, as your ampm or any other String you are trying to Access is null at this Point and you are trying to compare the null String with a string.
Make sure, that you initialize your Strings before you compare them with anything, for example with
String weekdayinput = "mo";
String weekday "mo";
int hour;
String ampm "am";
int time;
And you should call the functions for weekday and time after you asked for the Input.
Scanner input = new Scanner(System.in);
Call call1 = new Call();
System.out.println("To calculate the cost per minute of your long-distance call, we'll need some information.");
System.out.println(
"What hour are you planning on making the call. Minutes aren't necessary. Please only enter the hour number. (ex. 8)");
call1.hour = input.nextInt();
input.hasNextLine();
System.out.println("Is the call taking place AM or PM?");
call1.ampm = input.nextLine();
input.hasNextLine();
System.out.println("And what day of the week is that? Please enter weekday with only first two letters. (ex. Fr");
call1.weekdayinput = input.nextLine();
String weekday = call1.calculateweekday();
int time = call1.calculatetime();
And as a sidenote: You should read About switches which can replace this many if Statements.
Further thoughts
The Answer by Wuttke is correct and should be accepted. Here's a few more extraneous thoughts.
Generally best to keep each class in its own .java file.
Be careful with naming. Being descriptive and specific makes your code much easier to read, review, and revise. So call your Scanner object something like scanner rather than input.
You can shorten some logic by converting text inputs to all uppercase or lowercase.
Your code time > 1206 && time <= 1211 left me puzzled. I do not understand your intent.
Separate user-interface from business logic. The rules for days and times for various charges should be segregated to their own class. That makes for one place with very simple short code to read and edit when your business rules change. And business rules always change, eventually.
Do all the data-entry validation in your user-interface code, keeping that separated from your business logic code. Pass already-validated data to the business logic (here, the code that determines pricing). The idea is to focus on a single responsibility. The business logic code should only be burdened with the job of knowing the day & time pricing scheme, not interacting with the user. Likewise, the UI code should not know about the nitty-gritty details of call-costing, but should know only enough to validate data-entry.
Instead of the series of if statements, use switch as shown in the Oracle Tutorial.
Use smart objects rather than dumb strings or mere integers, whenever possible. Java offers the DayOfWeek enum, so use those seven pre-defined objects rather than clumsy strings. Likewise, we have a LocalTime class for time-of-day without date and without time zone.
Java has strong features for localizing. So no need to hard-code things like dollar sign and name of day-of-week.
Resources such as a Scanner should be closed when you are done using them. The try-with-resources syntax automates this chore.
Example code
Here is some example code. Not meant for production, not tested. But should prove interesting to someone learning Java.
In real work I would:
Do more error-checking, like checking for the scanner being closed.
Pull out each of the parsing sections (hour, AM/PM, and day-of-week) into subroutines (named private methods).
Replace the conventional switch statement to the new simplified switch statement being previewed in Java 12 & Java 13.
Give the user an exit option on every prompt, like q to quit.
Use unit testing to verify logic.
First, the business logic portion.
package work.basil.example;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
public class CallCostEstimator
{
private Set < DayOfWeek > weekdays = EnumSet.of ( DayOfWeek.MONDAY , DayOfWeek.TUESDAY , DayOfWeek.WEDNESDAY , DayOfWeek.THURSDAY , DayOfWeek.FRIDAY );
LocalTime daytimeStart = LocalTime.of ( 8 , 0 );
LocalTime daytimeStop = LocalTime.of ( 18 , 0 );
BigDecimal weekday_day_rate = new BigDecimal ( "4.5" );
BigDecimal weekday_night_rate = new BigDecimal ( "4.0" );
BigDecimal weekend_rate = new BigDecimal ( "2.25" );
public BigDecimal estimate ( LocalTime localTime , DayOfWeek dayOfWeek )
{
Objects.requireNonNull ( localTime );
Objects.requireNonNull ( dayOfWeek );
boolean isWeekday = ( weekdays.contains ( dayOfWeek ) );
boolean isDaytimeHours = ( ! localTime.isBefore ( this.daytimeStart ) ) && ( localTime.isBefore ( this.daytimeStop ) );
// Determine price slot
BigDecimal result = null;
if ( ! isWeekday )
{
result = this.weekend_rate; // In other cases we would make a copy before returning an object stored within this class. But `BigDecimal` is immutable, so not necessary.
} else
{ // Else is weekday.
if ( isDaytimeHours )
{
result = this.weekday_day_rate;
} else
{
result = this.weekday_night_rate;
}
}
if ( Objects.isNull ( result ) ) // Should not be possible if our cascade of `if` statements is complete and correct. Defensive programming requires that we check.
{
throw new IllegalStateException ( "Failed to find a price slot." );
}
return result;
}
}
And the user-interface portion.
package work.basil.example;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.format.TextStyle;
import java.util.*;
public class CallCostEstimateConsole
{
public static void main ( String[] args )
{
CallCostEstimateConsole app = new CallCostEstimateConsole ();
app.engageUser ();
}
public void engageUser ( )
{
// Use try-with-resources syntax to auto-close the scanner.
try (
Scanner scanner = new Scanner ( System.in ) ;
)
{
System.out.println ( "To calculate the cost per minute of your long-distance call, we'll need some information." );
Integer hour = null;
while ( Objects.isNull ( hour ) )
{
System.out.println ( "What hour are you planning on making the call? Minutes aren't necessary. Please only enter the hour number, 1-12 for 12-hour clock. (ex. 8)" );
try
{
int input = scanner.nextInt ();
if ( ( input < 1 ) || ( input > 12 ) )
{
System.out.println ( "Hour must be from 1 to 12." );
} else
{
hour = input;
}
} catch ( InputMismatchException e )
{
System.out.println ( "Error: Enter a digits only, for a number from 1 to 12. " );
}
}
String amPm = null;
while ( Objects.isNull ( amPm ) )
{
System.out.println ( "Is the call taking place AM or PM? (type either AM or PM, or am or pm)" );
String input = scanner.next ();
input = input.toUpperCase ();
if ( input.equals ( "AM" ) || ( input.equals ( "PM" ) ) )
{
amPm = input;
} else
{
System.out.println ( "You typed something other than AM or PM." );
continue;
}
// Tweak inputs for 12-hour to 24-hour conversion.
if ( amPm.equals ( "AM" ) && ( hour == 12 ) )
{
hour = 0;
}
}
// If 1 PM through 11 PM, add 12 hours for 24-hour time.
hour = ( amPm.equals ( "PM" ) & ( hour < 12 ) ) ? ( hour + 12 ) : hour; // Ternary statement. A compact alternative to an `if` statement.
LocalTime localTime = LocalTime.of ( hour , 0 );
DayOfWeek dayOfWeek = null;
while ( Objects.isNull ( dayOfWeek ) )
{
System.out.println ( "And what day of the week is that? Please enter weekday with only first two letters. (ex. Fr)" );
try
{
String input = scanner.next ().toLowerCase ();
if ( input.isEmpty () )
{
System.out.println ( "You did not type any characters. " );
continue; // Break-out to continue on to the next loop.
}
// Parsing logic.
switch ( input )
{
case "mo":
dayOfWeek = DayOfWeek.MONDAY;
break;
case "tu":
dayOfWeek = DayOfWeek.TUESDAY;
break;
case "we":
dayOfWeek = DayOfWeek.WEDNESDAY;
break;
case "th":
dayOfWeek = DayOfWeek.THURSDAY;
break;
case "fr":
dayOfWeek = DayOfWeek.FRIDAY;
break;
case "sa":
dayOfWeek = DayOfWeek.SATURDAY;
break;
case "su":
dayOfWeek = DayOfWeek.SUNDAY;
break;
default:
String message = "You did not type a 2-letter day-of-week code as expected. (Mo, Tu, We, Th, Fr, Sa, Su)";
throw new IllegalStateException ( message );
}
} catch ( InputMismatchException e )
{
System.out.println ( "Error: Enter a digits only, for a number from 1 to 12. " );
}
}
// Calculate result.
CallCostEstimator estimator = new CallCostEstimator ();
BigDecimal estimate = estimator.estimate ( localTime , dayOfWeek );
// Report result.
String output = NumberFormat.getInstance ( Locale.US ).getCurrencyInstance ().format ( estimate );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime ( FormatStyle.SHORT ).withLocale ( Locale.US );
String dow = dayOfWeek.getDisplayName ( TextStyle.FULL , Locale.US );
String message = "Your call at " + localTime.format ( f ) + " on " + dow + " will cost per minute: " + output;
System.out.println ( message );
}
}
}
Example run.
To calculate the cost per minute of your long-distance call, we'll need some information.
What hour are you planning on making the call? Minutes aren't necessary. Please only enter the hour number, 1-12 for 12-hour clock. (ex. 8)
1
Is the call taking place AM or PM? (type either AM or PM, or am or pm)
am
And what day of the week is that? Please enter weekday with only first two letters. (ex. Fr)
mo
Your call at 1:00 AM on Monday will cost per minute: $4.00

Finding day of week given date (no libs or package imports allowed)

I want to create a Java Program that takes a date as input (27,2,2019) and print out what day it was. I am just assuming the usage of Gregorian Calender only. The reference is 1,1,1 which is a Monday. I am unable to complete this. Can someone help me out please. I also took leap years to account. Also, in this project, I am not allowed to import any packages so I should do it normally.
public class sortday
{
public static void main (String [] args)
{
sortdayoftheyear(1,1,2019);
}
public static void sortdayoftheyear(int day, int month, int year)
{
final int [] months = {31,28,31,30,31,30,31,31,30,31,30,31};
{
final int monthnum = 12;
int totaldays=0;
int newmon = month-1; //find which month it is
int monthdays = months[newmon]; // find days of the month
for (int i = 1; i < year; i++)
{
if (i%100 != 0 && i%4 == 0 && i%400 == 0) //check for leap year
{
totaldays = i*366;
}
else
totaldays = i*365;
}
totaldays += (day) + (newmon*monthdays);
if (totaldays%7 == 4)
System.out.println("Sunday");
if (totaldays%7 == 5)
System.out.println("Monday");
if (totaldays%7 == 6)
System.out.println("Tuesday");
if (totaldays%7 == 0)
System.out.println("Wednesday");
if (totaldays%7 == 1)
System.out.println("Thursday");
if (totaldays%7 == 2)
System.out.println("Friday");
if (totaldays%7 == 3)
System.out.println("Saturday");
System.out.println("It had been " + totaldays + " since January 1,AD");
}
}
}
There seems to be more than one bug in your code. I have spotted:
Each time through your for loop you are assigning a new value to totaldays. In this way only the last time through the loop has any effect in the end. I believe you intended every iteration to contribute.
As yole said in a comment, newmon*monthdays is incorrect for the total number of days in the first newmon months of the year. I even think that for February 13 your are counting 13 + 1 * 28, which can’t be right. One suggestion is you loop through the months and add up their lengths.
If the entered year is a leap year, you are always counting 28 days in February. You want to count 29 sometimes. An auxiliary method to determine whether a year is a leap year would come in handy.
If your reference date of January 1, 1 is a Monday, I think you want to print this when the modulo operation in the end yields 1. You are printing Thursday in this case.
I can’t tell if there may be more.
Issues without functional consequences that you should nevertheless want to fix include:
You are not using the constant monthnum, so delete it.
You have a superfluous set of braces around the code piece from the mentioned constant down to System.out.println. Delete those too.
Get your indentation right so you and I can read your code.
When writing code for others to read (including Stack Overflow users), respect the naming conventions. Call the class SortDay or FindDayOfWeek. The method sortDayOfTheYear or printDayOfWeek.

Java while loop stopping before all conditions are met

I have a project where my method gets two dates and it keeps adding a day to the method until both dates are equal and then you can see how far apart the date were by seeing how many times a day was added. My problem is that my while loop is exiting out when the the day condition is met even though the day, month, and year must all be the same for it to stop working
while (pastDate.getDay() != futureDate.getDay() &&
pastDate.getMonth() != futureDate.getMonth() &&
pastDate.getYear() != futureDate.getYear()){
You need to OR together the conditions in your while loop:
while (pastDate.getDay() != futureDate.getDay() ||
pastDate.getMonth() != futureDate.getMonth() ||
pastDate.getYear() != futureDate.getYear()) {
// do something
}
In pseudo-code, the logic for the loop when the two dates are equal would be:
while (day1 == day2 && month1 == month2 && year1 == year2) {
// ...
}
By the DeMorgan's Laws, the opposite of P AND Q is ~P OR ~Q, which would lead the following while loop (again in pseudo-code) for when the dates are not equal:
while (day1 != day2 || month1 != month2 || year1 != year2) {
// ...
}
Use .equals():
while (!pastDate.equals(futureDate)) {
//
}
Not only is it more readable, it leaves exactly how dates are considered equal to the implementation, which is where OOP best practices says it should be.

Java, I dont understand why this is happening, variable changes

public void askForDate(Scanner in) {
System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");
String enteredDate = in.nextLine();
//This array will hold the 3 elements of which the date is made up of, day, month and year, and this method returns it.
String[] dateEnteredSplit = enteredDate.split("/");
//I am using the split method to seperate each number, which returns an array, so I am assigning that array to the dateEnteredSplit array.
//dateEnteredSplit = enteredDate.split("/");
//So now the first element holds the day, second the month, and the third element holds the year.
//System.out.println(Arrays.toString(dateEnteredSplit));
//Assigning each element and converting them to integers.
int day = Integer.parseInt(dateEnteredSplit[0]);
int month = Integer.parseInt(dateEnteredSplit[1]);
int year = Integer.parseInt(dateEnteredSplit[2]);
**System.out.println("day: " + day + " month: " + month + " year: " + year);**
//The loop will be entered if any of the values are wrong. which will use recursion to call this method again for a chance to enter the date again.
while (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000)) {
**System.out.println("day: " + day + " month: " + month + " year: " + year);**
//Im calling these methods to inform which one specifially was wrong so they know what they need to change.
this.setDay(day);
this.setMonth(month);
this.setYear(year);
dateEnteredSplit[0] = "0";
askForDate(in);
}
//I then assign any correct value into the object attribute because the while loop is either finished or not entered at all.
//No need to use setDay etc. here because the checks have been done above in the while loop.
this.day = day;
this.month = month;
this.year = year;
}
Ok that is a method in a class. It asks for input in the format dd/mm/yyyy
If the first time I input 12/1/1996 it works, but if I enter a wrong date for example like this first, 123/123/123 and the enter a correct date for example 12/1/1996, it still enters the loop.
After debugging, the first line that is bold, the values are different from the second line that is bold, its like the values are changing by their own.
What is the problem here? I have been trying to find out in the past 1 hour.
Thanks in advance!
The problem very likely is in the way you are trying to combine recursive and iterative approach to update values (there is a while loop, that call the function recursively, which may also trigger while loop in next level of call and the previous one will continue calling itself recursively and you will end up with just mess)
There is no real reason to do that recursively, I would do iterative only approach, something like this:
public void askForDate(Scanner in) {
System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");
int day, month, year;
do { // We use do-while to get the first read without condition, although setting date to invalid value (like day = 0) and then running standard while loop will work just as fine
String[] dateEnteredSplit = in.nextLine().split("/");
//Assigning each element and converting them to integers.
day = Integer.parseInt(dateEnteredSplit[0]);
month = Integer.parseInt(dateEnteredSplit[1]);
year = Integer.parseInt(dateEnteredSplit[2]);
} while (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000));
// Now day month and year variables are set correctly and we can do stuff with it
}
If you insist or recursive approach, the correct way would be to call the function just once:
public void askForDate(Scanner in) {
System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");
int day, month, year;
String[] dateEnteredSplit = in.nextLine().split("/");
//Assigning each element and converting them to integers.
day = Integer.parseInt(dateEnteredSplit[0]);
month = Integer.parseInt(dateEnteredSplit[1]);
year = Integer.parseInt(dateEnteredSplit[2]);
if (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000)) askForDate(in);
// You need to save day/month/year variables to other than local scope (like this.day = day)
// Otherwise it would just somewhere in recursion stack and you wouldn't be able to use it
}
Just to be complete, keep in mind that date string could be wrong in other way that just number out of range. What if user types 1. 2. 3456 or a/b/c or not even something very different like Hello
At your snippet of code would crash (either throw NumberFormatException when trying to parse non-integer or ArrayIndexOutOfBoundsException when accessing dateEnteredSplit array at element that doesnt exists (there are no '/' in 'Hello'))
Here is what happens. Wrong values on a first while loop iteration make a call to askForDate possible. You receive a second prompt and provide correct input. The second call of askForDate ends as expected. The execution returns again to a while loop, where you still have the first wrongly set values and the process starts again.
If you really do want to use recursion here, you should return a value from your function (dates or boolean flag) and check it in a while loop condition.

Java leapyear check program. No response to edge values

I'm working on a program for school to take a year input from the user and check to see if it is a leap year or not. It should also check to see if the year is prior to 1582 and return an error if it is. I'm having an issue that if the user enters a year between [1582, 1599] that the program halts and doesn't print anything. If I change the value to 1600 it doesn't return anything between [1600, 1639]. Not sure why this behavior is happening. Any help would be appreciated.
import java.util.Scanner;
public class Leapyear {
public static void main(String[] args) {
Scanner Jeff = new Scanner(System.in);
//System.out.print("Run Leapyear progra? Enter true or false: ");
//boolean RunLoop$ = Jeff.nextBoolean();
System.out.print("\nPlease enter a year: ");
int Year = Jeff.nextInt();
//while(RunLoop$ = true)
if (Year <= 1582)
System.out.println("The entered year is prior to the Gregorian Callandar");
else
if (Year % 4 == 0)
if (Year % 400 + Year % 100 == 0)
System.out.println("The entered year is a leapyear");
else
System.out.println("The Entered year is not a leapyear");
}
}
Your if statements are incorrect. I second David's comment and strongly advise to use brackets for every if statement (which is also recommended in the - albeit ancient, but mostly still valid - Code Conventions for the Java Programming Language).
Furthermore, switching to a decent IDE and/or making use of its source code formatting support will greatly help you with these kinds of issues.
A simple (automatic) cleanup leads to the following snippet for your if statements, which is fully equivalent in terms of application logic:
if (Year <= 1582) {
System.out.println("The entered year is prior to the Gregorian Callandar");
} else if ((Year % 4) == 0) {
if (((Year % 400) + (Year % 100)) == 0) {
System.out.println("The entered year is a leapyear");
} else {
System.out.println("The Entered year is not a leapyear");
}
} // else?
You can now clearly see that there won't be any output if Year is greater than 1582 but not divisible by 4.
if you don't use the {} curly brackets for every if and else statement then it will only consider the first line after the condition so in
else
[empty line]
if (Year %4 ==0)
[empty line]
means after else it will do nothing the same after the if because only the first line under it is considered which is empty.
Another problem you'll be having is that your while loop will go forever :) since the boolean value will always remain true. If you want to make user insert a new value each time then just insert at the end of the while loop.
System.out.print("add another year ? ");
RunLoop$ = Jeff.nextBoolean();
Year = Jeff.nextInt();`
or add Jeff.hasnextInt()in the while loop condition instead removing the Boolean entirely so when user enters anything other than an int value the loop breaks.while(Jeff.hasnextInt()) and at the end of the loop.
System.out.print("add another year ? ");
Year = Jeff.nextInt();`

Categories

Resources