MATLAB: Can’t the function handle the error in a given date input

MATLABmatlab function

I'm studying MATLAB on coursera and stuck with a question:
Write a function called day_diff that takes four scalar positive integer inputs, month1, day1, month2,day2. These represents the birthdays of two children who were born in 2015. The function returns a positive integer scalar that is equal to the difference between the ages of the two children in days. Make sure to check that the input values are of the correct types and they represent valid dates. If they are erroneous, return -1. An example call to the function would be
>> dd = day_diff(1,30,2,1);
which would make dd equal 2. You are not allowed to use the built-in function datenum or datetime. Hint: store the number of days in the months of 2015 in a 12-element vector (e.g., 31, 28, 31, 30 …) and use it in a simple formula.
Multiple cases are tested using a pre-made evaluation code.
My code so far:
function answer = day_diff(month1, day1, month2,day2)
answer = -1;
days_in_months = [31,28,31,30,31,30,31,31,30,31,30,31]; %days in every month array
flag1 = days_in_months(month1); %to check if day1 is valid
flag2 = days_in_months(month2); %to check if day2 is valid
%Non valid values handing
if nargin < 4
error('Must have four arguments');
end
if ~isscalar(month1) || month1 < 1 || month1 ~= fix(month1) || month1 > 12
error('month1 needs to be a positive integer and not greater than 12.');
end
if ~isscalar(month2) || month2 < 1 || month2 ~= fix(month2) || month2 > 12
error('month2 needs to be a positive integer and not greater than 12.');
end
if ~isscalar(day1) || day1 < 1 || day1 ~= fix(day1)|| day1 > flag1
error('day1 needs to be a positive integer and a valid date.');
end
if ~isscalar(day2) || day2 < 1 || day2 ~= fix(day2)|| day2 > flag2
error('day1 needs to be a positive integer and a valid date.');
end
%end of error handler
%to find the age in days
if (month1 == month2)
inbetween_days = 0;
if day1 == day2
first_last_days = 0;
elseif day1 < day2
first_last_days = day2 - day1;
else
first_last_days = day1 - day2;
end
elseif month1 < month2
inbetween_days = sum(days_in_months(month1+1:month2-1));
first_last_days = (days_in_months(month1)-day1) + day2;
else
inbetween_days = sum(days_in_months(month2+1:month1-1));
first_last_days = day1 + (days_in_months(month2)-day2);
end
answer = first_last_days + inbetween_days;
end
so far so good but when it's day_diff(2, 29, 1, 22), the evaluation file gives an error instead of handling the wrong pre-defined input (day1 is 29 and maximum is 28), is the problem in how to return the -1 ?
Problem 4 (day_diff):
Feedback: Your function performed correctly for argument(s) 1, 30, 2, 1
Feedback: Your function performed correctly for argument(s) 1, 1, 1, 1
Feedback: Your function performed correctly for argument(s) 1, 1, 1, 2
Feedback: Your function performed correctly for argument(s) 1, 2, 1, 1
Feedback: Your function performed correctly for argument(s) 1, 1, 2, 1
Feedback: Your function performed correctly for argument(s) 2, 1, 1, 1
Feedback: Your function performed correctly for argument(s) 1, 31, 2, 1
Feedback: Your function performed correctly for argument(s) 2, 1, 1, 31
Feedback: Your function performed correctly for argument(s) 1, 1, 12, 31
Feedback: Your function performed correctly for argument(s) 2, 1, 3, 1
Feedback: Your function performed correctly for argument(s) 7, 1, 9, 30
Feedback: Your program made an error for argument(s) 2, 29, 1, 22
Your solution is _not_ correct.

Best Answer

Your function errors if the inputs are invalid. In my opinion, it's much better coding than what you are asked, but you are asked to return -1, not error if the inputs are invalid. Therefore, yes, what you have coded is going to fail the autograder.
That is easily fixed, replace all the error calls by a simple return.
As said, in term of design, it's much better to error than return -1. So for a real program, for an even better design, I would use validateattributes rather than coding the checks myself:
narginchk(4, 4); %rather than coding the check of the number of inputs yourself
validateattributes(month1, {'numeric'}, {'integer', 'scalar', 'positive', '<=', 12}, 1);
validateattributes(day1, {'numeric'}, {'integer', 'scalar', 'positive', '<=', flag1}, 2);
%etc.
But again, here, you must return instead of erroring..
Also, in terms of design
  • the names flag1 and flag2 are misleading, I would call these variables something else more representative of what they do. Typically, variables named flags only have two states.
  • You should index days_in_months using month1 or month2 only after you've checked that month1 or month2 is valid. Otherwise, your indexing operation may error.