how can i solve this ,can anyone provide me with code? whats wrong with my code ?
Info
This question is locked. Reopen it to edit or answer.
Show older comments
Write a function called valid_date that takes three positive integer scalar inputs year, month, day. If these three represent a valid date, return a logical true, otherwise false. The name of the output argument is valid. If any of the inputs is not a positive integer scalar, return false as well. Note that every year that is exactly divisible by 4 is a leap year, except for years that are exactly divisible by 100. However, years that are exactly divisible by 400 are also leap years. For example, the year 1900 was not leap year, but the year 2000 was. Note that your solution must not contain any of the date related built-in MATLAB functions.
function [valid]=valid_date(year, month, day)
if isscalar(year) && year>0 && year~=0 && isscalar(month) && month>0 && month~=0 && isscalar(day) && day>0 && ar
if mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0 && month==2 && days<=29
%for february
valid=true;
else
valid=false;
end
%for rest of the months
if month==4 || month==6 || month==9 || month==11 && day<=30
valid=true;
elseif month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12 && day<=31
valid=true;
else
valid=false;
end
%not a leap year
if month==2 && day>28
valid=false;
end
%rest of the months
if month==4 || month==6 || month==9 || month==11 && day<=30
valid=true;
elseif month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12 && day<=31
valid=true;
else
valid=false;
end
else
valid=false;
end
21 Comments
Geoff Hayes
on 28 Mar 2019
asad - why do you think there is something wrong with your code? Is there a particular case where it fails? What are the inputs that you are providing to this function? Please provide details.
Geoff Hayes
on 28 Mar 2019
definitely your condition here is incorrect
if month==4 || month==6 || month==9 || month==11 && day<=30
You probably want to wrap the the month number conditions in brackets like
if (month==4 || month==6 || month==9 || month==11) && day<=30
Same for the other condition for those months with 31 days.
asad jaffar
on 28 Mar 2019
asad jaffar
on 28 Mar 2019
asad jaffar
on 28 Mar 2019
Edited: Voss
on 30 Oct 2024
Geoff Hayes
on 28 Mar 2019
asad's answer moved here
its giving some error about atleast one end is missing ,
Geoff Hayes
on 28 Mar 2019
asad - please further the conversation with comments either here or at Jan's answer...rather than using "answers" to do the same.
As for the missing "end" you will need to show the code that you have now because that which you have posted above seems to have and "end" for each "if" block.
asad jaffar
on 28 Mar 2019
Walter Roberson
on 28 Mar 2019
I have attached the code from your original post, modified to have appropriate () for the if statements. It does not have any problem with missing end statements.
The code has a lot of problems, which Jan explained to you, so you will need to improve it. But at least this will get you past the missing END problem.
Geoff Hayes
on 28 Mar 2019
can't be the same code...when I run the above I get the same failure that Jan indicated below (the undefined ar variable). And when I remove it and put in the brackets like I suggested, I get an answer (which may or may not be valid).
asad jaffar
on 29 Mar 2019
asad jaffar
on 29 Mar 2019
asad jaffar
on 29 Mar 2019
The code posted in the question was taken from: https://www.mathworks.com/matlabcentral/answers/445601-can-anyone-point-out-the-mistake-in-this-program-it-s-regarding-writing-a-function-to-check-if-the
By the way, 9 lines are enough (including the function and end lines).
Aman Gupta
on 26 Jun 2019
Write a function called valid_date that takes three positive integer scalar inputs year, month, day. If these three represent a valid date, return a logical true, otherwise false. The name of the output argument is valid. If any of the inputs is not a positive integer scalar, return false as well. Note that every year that is exactly divisible by 4 is a leap year, except for years that are exactly divisible by 100. However, years that are exactly divisible by 400 are also leap years. For example, the year 1900 was not leap year, but the year 2000 was. Note that your solution must not contain any of the date related built-in MATLAB functions.
SOLUTION IS HERE
function valid = valid_date(year,month,day)
t = (isscalar(year) && isscalar(month) && isscalar(day));
if (t == 0);
valid = t;
else
T = ((nargin == 3) && (year>0) && ((month > 0) && (month <=12)) && ((day > 0) && (day<=31)));
if T
persistent Div_by_Four;
persistent Div_by_FHun;
persistent div_by_hund;
persistent leap_year;
leap_year=0;
Div_by_Four = rem(year,4);
Div_by_FHun = rem(year,400);
div_by_hund = rem(year,100);
if (Div_by_Four == 0)
leap_year = 1;
end
if (div_by_hund == 0)
leap_year = 0;
end
if (Div_by_FHun == 0)
leap_year = 1;
end
if (leap_year == 1 && month == 2)
valid = day<=29;
elseif (month<=7)
if(month == 2)
valid = day<=28;
elseif (rem(month,2) == 0)
valid = day<=30;
else
valid = day<=31;
end
else
if (rem(month,2) == 0)
valid = day<=31;
else
valid = day<=30;
end
end
else
valid = T
end
end
Mohd Sharique Khan
on 27 Jun 2019
ans
function valid = valid_date(year,month,day)
%check the input are positive integer or not
if ~isscalar(year) || year<1 || year ~= fix(year)
valid = false;
return
end
%find out wether it is leapyear or not
if ~mod(year,4)
if ~mod(year,100)
if ~mod(year,400)
leap = 1;
else
leap = 0;
end
else
leap = 1;
end
else
leap = 0;
end
month_verification = [31 28+leap 31 30 31 30 31 31 30 31 30 31 ];
if ~isscalar(month) || ~(month>0 && month<=12) || month ~= fix(month)
valid = false;
return
end
if ~isscalar(day) || ~(day>0 && day<=month_verification(month)) || day ~= fix(day)
valid = false;
return
end
valid = true;
Jan
on 28 Jun 2019
@Aman Gupta: There is no need to declare the variables as persistent.
@Mohd Sharique Khan: Please post answers in the section for answers.
vidushi Chaudhary
on 16 May 2020
Can anyone explain how nested if exactly works to calculate leap year in @Mohd Shafique Khan answer
Walter Roberson
on 16 May 2020
If the year is not a multiple of 4, then you already know that this is not a leap year, so you can skip further examination. If the year is divisible by 4 but is not a multiple of 100, then you can be sure that it is a leap year without further checks. If the year is divisible by 4 and is divisible by 100 then it is a leap year if it is a multiple of 400 and is not a leap year otherwise (so 2000 -> leap year, 2100 -> not, 2200 -> not, 2300 -> not, 2400 -> leap year.)
Huseyn Mammadli
on 27 Jul 2020
Someone can help me? Why This code giving error o submit?
function [valid] = valid_date(year,month,day)
% Month 2
if ((mod(year,100)==0) && (mod(year,400)~=0))&& (month == 2) && (day < 29)
valid = true;
elseif ((mod(year,100)==0) && (mod(year,400)~=0))&& (month == 2) && (day > 28)
valid = false;
elseif ((mod(year,100) == 0) && (mod(year,400)==0)) && (month == 2) && (day < 30)
valid = true;
elseif ((mod(year,100) == 0) && (mod(year,400)==0)) && (month == 2) && (day > 29)
valid = false;
elseif (mod(year,4)==0)&& (month == 2) && (day < 30)
valid = true;
elseif (mod(year,4)==0)&& (month == 2) && (day > 29)
valid = false;
elseif (mod(year,4) ~=0)&&(month==2) &&(day>28)
valid = false;
elseif (mod(year,4) ~=0)&&(month==2) &&(day<29)
valid = true;
end
% Month 31
if (month == 1 ||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12)&& (day < 32)
valid=true;
else
valid = false;
end
% Month 30
if (month == 4 ||month == 6||month == 9||month == 11)&& (day < 31),valid=true;
else
valid = false;
end
@Husein Mammadli: Which error message do you get? This message reveals the problems usually.
Your code does not check if the inputs are scalars or have positive integer values. The code distinguishes two cases for Frebrurary:
- ((mod(year,100)==0) && (mod(year,400)~=0))
- (mod(year,4)==0)
This is not useful. You need to detect leap years only:
~mod(year, 4) && mod(year, 100) || ~mod(year, 400)
You can simplify your code:
function valid = valid_date(year,month,day)
if month == 2 % Month 2
if mod(year, 4)==0 && mod(year, 100) || ~mod(year, 400) % Leap year
valid = (day < 30);
else % Not leap year
valid = (day < 29);
end
elseif any(month = [1,3,5,7,8,10,12]) % Months with 31 days
valid = (day < 32);
else % Months with 30 days
valid = (day < 31);
end
end
But the error checks of the inputs are still missing.
Answers (19)
function valid = valid_date(year, month, day)
% scalar positive integer limit
if isscalar(year) && year > 0 && fix(year) == year && ...
isscalar(month) && month > 0 && fix(month) == month && month <= 12 && ...
isscalar(day) && day > 0 && fix(day) == day
% Leap year: multiple of 4, but not of 100, or of 400:
isLeap = (~mod(year, 4) && mod(year, 100) || ~mod(year, 400));
% Valid days:
% * month is 4,6,9,11 and days <= 30,
% * month is 2 and days <= 28 or 29 for leap years
% * other month and days <= 31
valid = (any(month == [4,6,9,11]) && day <= 30) || ...
(any(month == [1,3,5,7,8,10,12]) && day <= 31) || ...
(month == 2 && day <= 28 + isLeap);
else
valid = false;
end
end
Or:
function valid = valid_date(year, month, day)
% Anonymous function to check for positive integer scalar values:
ok = @(x) isscalar(x) && x > 0 && fix(x) == x;
valid = false; % Default answer
% Check if all inputs are clean:
if ok(year) && ok(month) && month <= 12 && ok(day)
% Check if it is a leap year:
isLeap = (~mod(year, 4) && mod(year, 100) || ~mod(year, 400));
% Number of days per month, consider leap year for februrary:
d = [31, 28+isLeap, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
% The actual comparison:
valid = (day <= d(month));
end
19 Comments
asad jaffar
on 30 Mar 2019
Edited: Walter Roberson
on 31 Jul 2022
asad jaffar
on 30 Mar 2019
Edited: asad jaffar
on 30 Mar 2019
You have a decent kind of humor, asad jaffar. If you are still confused, although you can find 4 completely working codes in this thread, the best option is to take a break and to drink a cup of coffee! :-)
"just write me the code from A TO Z in order"
sort('A':'Z')
Good luck.
@Users of coursera: Sorry for posting working solutions. After this lengthy discussion I lost my patients. Feel free to write your own code and see my solution only as an alternative for educational purpose.
asad jaffar
on 30 Mar 2019
asad jaffar
on 30 Mar 2019
@asad: Your questions about Matlab are welcome and the topic of this forum. I'm glad if I can help you, but I'm not sure if posting a working solution is a real help, because it might reduce your chances to learn by your own.
Now you see 4 working solutions in this thread and it seems like you have problems with a copy&paste. Therefore a cup of coffee is a serious advice, while sort('A':'Z') is a joke only.
Please provide any information about the failing tests. This would allow for fixing the code. Do not let us guess, what the problems are. Please try to make it as easy as possible to help you. Just stating, that it does not work, is not helpful, most of all if e.g. Oleksandr tells you, that the same code is working for him successfully.
asad jaffar
on 31 Mar 2019
Walter Roberson
on 31 Mar 2019
His code works for me when I test.
@asad: What do you expect me to do? I've posted 3 methods which are working correctly on my computer. Oleksandr's version is fine also and it replies the correct answers for him, Walter and me. Therefore I assume, that the problem happens, when you copy&paste the code. You provide the vague description "the last day of every month and random dates" only, but I cannot guess, which test is exactly failing. Maybe the test considers 0 as valid year, or Inf or NaN is provided as input. I do not have any chance to guess this. As long as you do not explain, for which input the posted methods fail, I cannot help you. So please answer:
For which input is the method failing? If coursera does not reveal this detail, there is no chance that I can guess this. Contact the authors and ask for details. Remember, that I cannot even see the output of the coursera and it would be your job to share these information.
See this test:
for k = 2:48000 % 0001-31-01 to 4000-11-30
d = datenum([1, k, 1, 0, 0, 0]) - 1; % Last date of each month
v = datevec(d); % [Year, Month, Day, H, M, S]
if ~valid_date(v(1), v(2), v(3))
disp(v(1:3)); % Display failing dates
end
end
This shows, that Oleksandr's and my suggestion do work correctly for the last days of each month from January 0001 to November 4000, and if you like you can expand the tests. In consequence if the test for "the last day of every month" fails, this must be a problem of the test or you made an error during pasting the working solution.
You make it hard to help you. For me this thread is frustrating. If you do not provide an evendince that there is a problem in the codes, I will consider the problem as solved or not solvable.
asad jaffar
on 1 Apr 2019
Stephen23
on 1 Apr 2019
+1 your second version is a very tidy and compact use of MATLAB.
asad Jaffar
on 1 Apr 2019
What?
Jan
on 1 Apr 2019
@asad: "+1" means, that Stephen was so kind to vote for my answer. He mentioned, that my 2nd suggested code uses a compact Matlab style.
asad jaffar
on 30 Apr 2019
Jan
on 2 May 2019
I'm fine, asad jaffar. Do the posted solutions work for you now?
Jan
on 6 Sep 2019
Hey Jan, really loved your very precise and explicit code, however I need some more clarifications. Could you please kindly comment out your code especially from the 'isLeap' output argument. ..Thanks
Walter Roberson
on 6 Sep 2019
mod(year,400) is 0 if the year is a multiple of 400. ~mod(year,400) is 1 if mod(year,400) is 0 . Thus ~mod(year,400) is true if the year is a multiple of 400, and is the same as mod(year,400) == 0
Krashank Kulshrestha
on 15 May 2020
Edited: Krashank Kulshrestha
on 15 May 2020
@jan ur 1st code is way better than elseif one i tried previously. Thanks.
Abhishek Kumar
on 6 Sep 2020
thank you so much it helps a lot.
Oleksandr Koreiba
on 30 Mar 2019
function valid = valid_date(year,month,day)
if isscalar(year)==true && year>0 && isscalar(month)==true && month>0 && 12>=month && isscalar(day)==true && day>0 %checks if input is correct
if (mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0) %checks if it's leap
isleap=true;
else
isleap=false;
end
if any(month == [4,6,9,11]) && day<=30 || any(month == [1,3,5,7,8,10,12]) && day<=31
valid = true;
elseif isleap == true && month == 2 && day<=29 || isleap == false && month ==2 && day<=28
valid=true;
else
valid=false;
end
else
valid=false;
end
end
Just beginner with matlab, had the same strugle. But with help from here managed to solve it. Maybe it will be helpful
9 Comments
asad jaffar
on 30 Mar 2019
@asad: Oleksandr's code works correctly and replies false for (2021, 11, 31), as expected.
A simplification:
- if isscalar(x)==true is the same as: if isscalar(x)
- if condition, y=true, else, y=false, end is equivalent to: y = condition
function valid = valid_date(year, month, day)
valid = false;
if isscalar(year) && year > 0 && isscalar(month) && ...
month > 0 && 12 >= month && isscalar(day) && day > 0
isleap = (mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0);
if any(month == [4,6,9,11]) && day <= 30 || ...
any(month == [1,3,5,7,8,10,12]) && day <= 31
valid = true;
elseif month == 2 && day <= 28 + isleap
valid = true;
end
end
end
Oleksandr Koreiba
on 30 Mar 2019
Edited: Oleksandr Koreiba
on 30 Mar 2019
Thanks for corrections.
Jan
on 30 Mar 2019
@Oleksandr: Your code worked correctly already, I just simplified it a little bit. This looks nicer and shorter code is less prone to typos.
samhitha sree
on 9 Jun 2019
can anyone please send me the correct and exact code please
Jan
on 10 Jun 2019
@samhitha sree: Seriously? You find several working codes in this thread already. Just copy&paste them.
anika kader
on 12 May 2020

anika kader
on 12 May 2020
whats wrong in my code

Walter Roberson
on 12 May 2020
If your first if fails then you do not set valid
Note: isscalar() already returns true or false; there is no need to compare the result to true.
if isscalar(year) && isscalar(month)
The code fails in the 2nd line, which ends with:
... isscalar(day) && day>0 && ar
What is the meaning of "ar"?
After checking month>0 there is no need to check for month~=0 because this is excluded already. But tis is not an error.
A problem is, that you check for a leap year at first:
if mod(year,4) == 0 && mod(year, 100)~= 0 || ...
mod(year,400)==0 && month==2 && days<=29
%for february
valid=true;
else
valid=false;
end
But afterwards this code runs also:
%not a leap year
if month==2 && day>28
valid=false;
end
This runs for leap years also and the former value of valid is overwritten.
Remember that the operator precedence (link) for && is higher than for ||. Then the test is equivalent to:
if (mod(year,4) == 0 && mod(year, 100)~= 0) || ...
(mod(year,400)==0 && month==2 && days<=29)
%for february
valid=true;
else
valid=false;
end
This sets valid to true for the inputs:
year = 2004;
month = 2;
days = 30;
because mod(year,4) == 0 && mod(year, 100)~= 0 is true already. You need to set the parentheses explicitly:
if (mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0) ...
&& month==2 && days<=29
I suggest to rewrite the code. Determine if it is a leap year at first:
isleap = (mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0);
Then check the validity for te months:
if any(month == [4,6,9,11]) % Nicer...
valid = (day<=30);
elseif ...
Then consider the leap year for the Februrary only.
28 Comments
asad jaffar
on 28 Mar 2019
Jan
on 28 Mar 2019
Sorry, asad jaffar, this is your course. Start with the last paragraph of my answer. Add an equivalent method for the months with 31 days. Then append the check for month==2 and use the value of isleap obtained before.
If I write this code completely for you, you will not learn how to program. So try it at first by your own. If you still have problems, post the code again and ask a specific question.
asad jaffar
on 28 Mar 2019
@asad jaffar: And if I will solve this question for you, you will stuck in the next task also.
I've posted almost the complete solution already, so you can use copy&paste to set it together. All you have to do is to appende this:
...
elseif any(month == [1, 3, 5, 7, 8, 10, 12]
isvalid = (day <= 31);
elseif month == 2
if mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0
isvalid = (day <= 29);
else
isvalid = (day <= 28);
end
end
Include the check if all inputs are scalar and >0 on top:
valid = false; % Default value
if ~(isscalar(year) && year > 0 && SAME FOR THE OTHER INPUT)
return;
end
Now you have all you need. 16 lines. Well, add a trailing end, so 17 lines. All you have to do is to copy&paste the code in the right order.
If you really need 14 hours to write this, you need to learn the basics of programming. The forum cannot and will not be a cheap programming service for you.
asad jaffar
on 29 Mar 2019
Jan
on 29 Mar 2019
The please post the code you have created and post the details of the problems. I can neither guess, what your final code is nor which problems it produces. Without knowing any details, I cannot suggest a solution.
asad jaffar
on 29 Mar 2019
asad jaffar
on 29 Mar 2019
Geoff Hayes
on 29 Mar 2019
looking at the screen capture of your code (you could attach the code itself...) it looks like there are some variables called isvalid rather than valid which is the output parameter (I guess this is for when you are checking for days in February). Have you tried to step through your code - with the debugger - to see why it might be failing for the two example calls that you have posted? Obviously the first date is valid and the second invalid...
asad jaffar
on 29 Mar 2019
asad jaffar
on 29 Mar 2019
asad jaffar
on 29 Mar 2019
Geoff Hayes
on 29 Mar 2019
it is giving correct answer for only' non leap years ' which leap year inputs/examples have you tried? Have you tried changing isvalid to valid?
asad jaffar
on 29 Mar 2019
Geoff Hayes
on 29 Mar 2019
Have you tried renaming the variable isvalid to valid?
asad jaffar
on 29 Mar 2019
Geoff Hayes
on 29 Mar 2019
what is the body of the first if statement in your above code? it looks like you just have an if with a bunch of conditions, no body and then and end. Do these conditions test the validity of your inputs (i.e. positive integers, etc.)? If so, shouldn't the remainder of the code that actually checks the date be the body within this if? So
valid = false;
if all three inputs are positive integer scalars then
check to see if valid date
end
The above isn't MATLAB code...
asad jaffar
on 29 Mar 2019
Walter Roberson
on 29 Mar 2019
maximum days in month is vector [31 28 31 30 31 30 31 31 30 31 30 31]
if is a leap year, maximum days in february is 29
assume you lose.
if month number is valid and day number is positive and day number is less than or equal to days-in-month indexed at month number then you win.
Jan
on 29 Mar 2019
@asad: If you post the code as text and not as screen shot, it is much easier to suggest an improvement.
asad jaffar
on 29 Mar 2019
asad jaffar
on 29 Mar 2019
Walter Roberson
on 29 Mar 2019
asad jaffar:
Start over. Re-read what I posted at https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687658
asad jaffar
on 29 Mar 2019
Walter Roberson
on 29 Mar 2019
I am not referring to the code I posted that fixed the "end" problem. I posted a completely different algorithm for you to follow. Give up on your existing code and write following the outline I showed. It is going to look like
- validate that the inputs are positive integer scalars, and that month number is not too much, and return false if they are not
- assignment of number of days of month
- test for leap year. Assignment of new value to number of days for february if so.
- test if the day provided is less than the number of days per month indexed at the month number, and return true if it is
- otherwise return false
asad jaffar
on 29 Mar 2019
asad jaffar
on 30 Mar 2019
Ajay Raineni
on 8 Apr 2020
Please did you passed assignment please help me please send me code
Parth Patel
on 1 Jun 2019
Edited: Parth Patel
on 1 Jun 2019
function valid = valid_date(y,m,d)
% check for positve scalar inputs
if (isscalar(y) && y>0 && y ~=0 ) && (isscalar(m) && m>0 && m~=0)&&(isscalar(d) && d>0 && d~=0)
% check for leap year
if mod(y,400) == 0
valid_leap = true;
elseif mod(y,4) == 0 && mod(y,100)~= 0
valid_leap = true;
else
valid_leap = false;
end
% check for february
if(valid_leap == true && m==2 && d <=29) || (valid_leap == false && m==2 && d<=28)
valid = true;
% check for rest of the months
elseif (m == 1 || m == 3 || m == 5 ||m == 7 ||m == 8 ||m == 10 ||m == 12 ) && d <= 31
valid= true;
elseif(m == 4 || m == 6 || m == 9 ||m == 11) && d <= 30
valid = true;
else
valid = false;
end
else
valid = false;
end
end
2 Comments
Walter Roberson
on 1 Jun 2019
(isscalar(y) && y>0 && m ~=0 )
It is not obvious why you have a month test with your year tests? You do not know yet that m is a scalar.
(isscalar(m) && m>0 && m~=0)
That re-tests m~=0 for no apparent reason?
Could you give an example of an m that could pass the m>0 test but fail m~=0 ?
Parth Patel
on 1 Jun 2019
apparently not
Aditi Sinha
on 17 Jun 2019
function [valid]=valid_date(year, month, day)
if isscalar(year)==1 && year>0 && year~=0 && isscalar(month)==1 && month>0 && month~=0 && isscalar(day)==1 && day>0 && month<=12
if mod(year,4)==0 && mod(year,100)~=0||mod(year,400)==0
if month==2
if day<=29
valid=true;
else
valid=false;
end
else if month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12
if day<=31
valid=true;
else
valid=false;
end
else if month==4 || month==6 || month==9 || month==11
if day<=30
valid=true;
else
valid=false;
end
end
end
end
else
if month==2
if day<=28
valid=true;
else
valid=false;
end
else if month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12
if day<=31
valid=true;
else
valid=false;
end
else if month==4 || month==6 || month==9 || month==11
if day<=30
valid=true;
else
valid=false;
end
end
end
end
end
else
valid=false;
end
3 Comments
Walter Roberson
on 17 Jun 2019
Could you give an example of a year that could pass the year>0 test but fail year~=0 ?
aakash re
on 13 May 2020
why do you have to add 3 ends after 2nd elseif
Rik
on 13 May 2020
Because those aren't elseifs, they are else followed by if.
if cond1
else if cond2
%some code
end
end
%this is equivalent to this:
if cond1
else
if cond2
%some code
end
end
Roshan Singh
on 21 Aug 2019
function valid=valid_date(year,month,day)
if (year>0 && month>0 && day>0 && month<13 && day<32 && isscalar(year)==1 && isscalar(month)==1 && isscalar(day)==1)
if (rem(year,400)==0)||((rem(year,4)==0)&&(rem(year,100)~=0))
switch month
case 1
if day<32
valid=true;
else
valid=false;
end
case 2
if day<30
valid=true;
else
valid=false;
end
case 3
if day<32
valid=true;
else
valid=false;
end
case 4
if day<31
valid=true;
else
valid=false;
end
case 5
if day<32
valid=true;
else
valid=false;
end
case 6
if day<31
valid=true;
else
valid=false;
end
case 7
if day<32
valid=true;
else
valid=false;
end
case 8
if day<32
valid=true;
else
valid=false;
end
case 9
if day<31
valid=true;
else
valid=false;
end
case 10
if day<32
valid=true;
else
valid=false;
end
case 11
if day<31
valid=true;
else
valid=false;
end
case 12
if day<32
valid=true;
else
valid=false;
end
end
else
switch month
case 1
if day<32
valid=true;
else
valid=false;
end
case 2
if day<29
valid=true;
else
valid=false;
end
case 3
if day<32
valid=true;
else
valid=false;
end
case 4
if day<31
valid=true;
else
valid=false;
end
case 5
if day<32
valid=true;
else
valid=false;
end
case 6
if day<31
valid=true;
else
valid=false;
end
case 7
if day<32
valid=true;
else
valid=false;
end
case 8
if day<32
valid=true;
else
valid=false;
end
case 9
if day<31
valid=true;
else
valid=false;
end
case 10
if day<32
valid=true;
else
valid=false;
end
case 11
if day<31
valid=true;
else
valid=false;
end
case 12
if day<32
valid=true;
else
valid=false;
end
end
end
else
valid=false
end
1 Comment
Your code probably work (I haven't tested) but you need to learn look-up tables. That many case statements must have been a pain to write and would certainly be a pain to maintain.
Your code using a look-up table
%note that this code, like yours will not work properly with non-integer inputs
function valid=valid_date(year,month,day)
numdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; %look-up table
if (year>0 && month>0 && day>0 && month<13 && day<32 && isscalar(year)==1 && isscalar(month)==1 && isscalar(day)==1)
monthday = numdays(month)
if (rem(year,400)==0)||((rem(year,4)==0)&&(rem(year,100)~=0)) && month==2
monthday = monthday + 1;
end
valid = day <= monthday
else
valid = false;
end
end
See how much simpler that is?
Doga Savas
on 23 Aug 2019
function a = valid_date(year,month,day)
if month > 12
a = false;
return
end
if ~isscalar(year) || year < 1 || year ~= fix(year)
a = false;
return
end
if ~isscalar(month) || month < 1 || month ~= fix(month)
a = false;
return
end
if ~isscalar(day) || day < 1 || day ~= fix(day)
a = false;
return
end
if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 ...
|| month == 10 || month == 12
if day > 31
a = false;
return
end
end
if month == 4 || month == 6 || month == 9 || month == 11
if day > 30
a = false;
return
end
end
if month == 2
if rem(year,4) == 0 && rem(year,100) ~= 0
if day > 29
a = false;
return
end
elseif rem(year,400) == 0
if day > 29
a = false;
return
end
else
if day > 28
a = false;
return
end
end
end
a = true;
end
1 Comment
Chech Joseph
on 6 Sep 2019
Hey Jan, really loved your very precise and explicit code, however I need some more clarifications. Could you please kindly comment out your code especially from the 'isLeap' output argument. ..Thanks
function valid = valid_date(year, month, day)
% scalar positive integer limit
if isscalar(year) && year > 0 && fix(year) == year && ...
isscalar(month) && month > 0 && fix(month) == month && month <= 12 && ...
isscalar(day) && day > 0 && fix(day) == day
isLeap = (~mod(year, 4) && mod(year, 100) || ~mod(year, 400));
valid = (any(month == [4,6,9,11]) && day <= 30) || ...
(any(month == [1,3,5,7,8,10,12]) && day <= 31) || ...
(month == 2 && day <= 28 + isLeap);
else
valid = false;
end
end
VIKAS JAIN
on 14 Sep 2019
function isvalid = valid_date(y, m, d)
% Check if the inputs are valid
% Check that they are scalars
if ~(isscalar(y) && isscalar(m) && isscalar(d))
isvalid = false;
% Check that inputs are positive
elseif ~all([y, m, d] > 0)
isvalid = false;
% Check that inputs are integers (not the data type)
elseif any(rem([y, m, d], 1))
isvalid = false;
% Check that m and d are below the max possible
elseif (m > 12) || (d > 31)
isvalid = false;
% The inputs could be a valid date, let's see if they actually are
else
% Vector of the number of days for each month
daysInMonth = [31 28 31 30 31 30 31 31 30 31 30 31];
% If leap year, change days in Feb
if isequal(rem(y, 4), 0) && (~isequal(rem(y, 100), 0) || isequal(rem(y, 400), 0)) daysInMonth(2) = 29;
end
maxDay = daysInMonth(m);
if d > maxDay
isvalid = false;
else
isvalid = true;
end
end
end
saud khan
on 9 Nov 2019
0 votes
Thank you very much everyone.
Marwan Hammad
on 19 Nov 2019
function valid = valid_date(year, month, day)
if nargin ==3
valid1=true;
else
error('must have three input arguments');
valid=false;
end
if isscalar(year)==true && isscalar(month)==true && isscalar(day)==true && year==fix(year) && month==fix(month) && day==fix(day)
valid2=true;
else
error('inputs must be a postive integers.');
valid=false;
end
if year>0 && year<2019 && month>0 && month<=12 && day>0 && day<=31
valid3=true;
else
error ('Please enter a valid date.');
valid = false;
end
if ~mod(year,4)
if ~mod(year,100)
if ~mod(year,400)
leap_year = 1;
else
leap_year = 0;
end
else
leap_year = 1;
end
else
leap_year = 0;
end
if (month== 1||3||5||7||8||10||12 && day<=31) && (month== 4||6||9||11 && day<=30)
valid4=true;
elseif ((leap_year==1 && (month==2 && day<=29))||((month==2 && day<=28) && leap_year==0))
valid5=true;
else
error ('Please enter a valid date.');
valid = false;
end
if valid1==true && valid2==true && valid3==true && valid4==true
valid = true;
elseif valid1==true && valid2==true && valid3==true && valid5==true
valid=true;
else
error ('Please enter a valid date.');
valid = false;
return
end
5 Comments
Rik
on 19 Nov 2019
The same question I posted on your other answer applies to this one as well: why post a function that doesn't seem to sattisfy the assignment? Several lines cannot be reached, it doesn't ever return an output if the date is invalid, and the return at the end is not needed.
Guillaume
on 20 Nov 2019
Has the code even been tested? If it had it would have been clear immediately that:
month== 1||3||5||7||8||10||12
doesn't do what's wanted.
Note that the above expression is always true (for scalar month).
Marwan Hammad
on 20 Nov 2019
It works with me man with any date you want
Guillaume
on 20 Nov 2019
It works with me
Again, have you tested it?
>> month = pi;
>> if (month== 1||3||5||7||8||10||12), disp('valid month'); else disp('invalid month'); end
valid month
>> month = -123456;
>> if (month== 1||3||5||7||8||10||12), disp('valid month'); else disp('invalid month'); end
valid month
Does it look like it's working correctly to you?
Let's try some:
valid_date(2016, 2, 29)
%returns true (correctly)
valid_date(2016, 2, 30)
%returns true (obviously incorrectly)
valid_date(2016, -2, 25)
%returns an error, instead of the logical false
And why did you decide to make 2019 as the last valid year?
So the conclusion is that your code only works for dates that are already valid, which is the thing this function is supposed to test. It will either error or it will return true if your date is not valid, so you can't distinguish valid dates from invalid ones with your implementation.
Yefferson Rodríguez
on 20 Nov 2019
Edited: Yefferson Rodríguez
on 20 Nov 2019
Hello,
Could someone help me with this?.
I wrote a code, which I think works fine when I try it on matlab.
but, once I summit it using the coursera system it says the opposite.
Thank you.
here is the code:
function valid = valid_date (year, month, day);
%Check if the input has 3 elements:
if nargin < 3;
error('The date must have 3 elements')
else
nargin==3;
validN=true;
end
%Check if the 3 elements are integer, scalars and positives:
%Also for month between 0 and 12.
%also fot days between 0 and 31.
if isscalar(year) && (not(mod(year,1))) == true && year>0
validY = true;
else
error('Year has to be integer, scalar and positive')
end
if isscalar(month) && (not(mod(month,1))) == true && month > 0 && month <= 12
validM = true;
else
error('Month has to be integer, scalar, positive and 0<m<=12')
end
if isscalar(day) && (not(mod(day,1))) == true && day > 0 && day <= 31
validD = true;
else
error('Day has to be integer, scalar, positive and 0<d<=31')
end
if (not(mod(year,4)) == true) && (not(mod(year,400)) == true)
if month == 1 || 3 || 5 || 7 || 8 || 10 || 12;
day <= 31;
elseif month == 2;
day <= 29;
elseif month == 3 || 4 || 6 || 9 || 11;
day <= 30;
end
else
if month == 1 || 3 || 5 || 7 || 8 || 10 || 12;
day <= 31;
elseif month == 2;
day <= 28;
elseif month == 3 || 4 || 6 || 9 || 11;
day <= 30;
end
end
if validN == true && validY == true && validM == true && validD == true
valid = true;
else
valid = false;
end
2 Comments
This is not an answer, but a question. Read the comments on other people posting here for further hints (or complete working solutions).
You might also try these three test cases:
valid_date(2016, 2, 29)
valid_date(2016, 2, 30)
valid_date(2016, -2, 25)
Some comments to the code:
- Do not set the value of nargin: nargin==3;
- If year is not a scalar the code proceeds. Then it must fail in
if (not(mod(year,4)) == true) && (not(mod(year,400)) == true)
- This will not do, what you expect:
if month == 1 || 3 || 5 || 7 || 8 || 10 || 12;
It is evaluated from left to right: month == 1 replies true or false. Afterwards true||1 or false||1 replies true in both cases. You mean:
if month == 1 || month == 3 || month == 5 || month == 7 || ...
month == 8 || month == 10 || month == 12
The code
if validN == true && validY == true && validM == true && validD == true
valid = true;
else
valid = false;
end
can be abbreviated to:
valid = validN && validY && validM && validD;
Comparing a logical value with true replies true if it is true and false otherwise. So this comparison is a waste of time. Simply use the logical value directly. The if can be omitted also.
Sandesh V
on 15 Apr 2020
%Can anyone please point out what's wrong with this code?
function valid = valid_date(year,month,day)
if (isscalar(year)==true && year>0 && isscalar(month)==true && month>0 && month<=12 && isscalar(date)==true && date>0)
if (mod(year,4)==0 && mod(year,100)~=0 || mod(year,400)==0)
if ((month==2 && date<=29) || ((month==4 || month==6 || month==9 || month==11) && day<=30) || ((month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) && day<=31))
% Leap year with other dates
valid = true;
else
valid = false;
end
else
if ((month==2 && day<=28) || ((month==4 || month==6 || month==9 || month==11) && day<=30) || ((month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) && day<=31))
valid = true;
else
valid = false;
end
end
else
valid = false;
end
end
2 Comments
Rik
on 15 Apr 2020
The structure of the code is not clear. That is probably an important reason why you are unable to find the mistake (if there is one, I haven't run your code).
Make the steps in your program clear. Do one step at a time and write a comment explaining what happens.
In this case the readability will probably improve a lot if you use a vector for the number of days in a month. That will also reduce the chance of typos.
Have a look at what the other functions in this thread are doing. There are several complete working examples, so learn from them.
And next time post your question as a question instead of an answer. You can find guidelines for posting homework on this forum here.
Sandesh V
on 15 Apr 2020
I found the error, I have used date instead of day in line2. Thanks for the input and I also from now on I will follow the guidelines for posting homework.
SWAROOPA SHIGLI
on 19 Apr 2020
Can anyone tell me why is this wrong?
function valid=valid_date(year,month,day)
if isscalar(year) && isscalar(month) && isscalar(day)
if (year>0 && (month>0 && month<13))
if month == [1 3 5 7 8 10 12]
if day>0 && day<32
valid=true;
else
valid=false;
end
elseif month == [4 6 7 9 11]
if day>0 && day<31
valid=true;
else
valid=false;
end
elseif month == 2
if year/4==0 || year/400==0
yr=leap;
if year/100==0 && year/400==0
yr=leap;
else
yr=nonleap;
end
else
yr=nonleap;
end
if ((day>0 && day<30) && yr==leap) || ((day>0 && day<29) && yr==nonleap)
valid=true;
else
valid=false;
end
end
else
valid=false;
end
else
valid=false;
end
2 Comments
Rik
on 19 Apr 2020
There are two things wrong with this post:
- it is not an answer, but a question
- you are checking for a leap year in an incorrect way. year/4 will not be equal to 0, unless year is 0, in which case that line will not be reached. You are also using leap and nonleap as variables or functions. You should use a logical scalar instead.
Walter Roberson
on 20 Apr 2020
You also are not checking that the inputs are integers.
Fazlul Haque
on 12 May 2020
function y= valid_date(a,b,c)
d31=[1 3 5 7 8 10 12];
d30=[4 6 9 11];
%for leap year
if (rem(a,4)==0 && rem(a,100)~=0) || rem(a,400)==0 LY=true;
else LY=false;
end
%for calculation
if sum(ismember(d31,b))==1 && c<=31
y=true;
elseif sum(ismember(d30,b))==1 && c<=30
y=true;
elseif b==2 && LY==false && c<=28
y=true;
elseif b==2 && LY==true && c<=29
y=true;
else y=false;
end
% for error check
if isscalar(a)==0 || isscalar(b)==0 || isscalar(c)==0 || nargin~=3
y=false;
return
end
if fix(a)~=a || fix(b)~=b || fix(c)~=c || a<1 ||b>12|| b<1 ||c>31||c<1
y=false;
end
what's wrong with this code?

3 Comments
Walter Roberson
on 12 May 2020
you need to test for scalar before you use && as && is only for scalars
Fazlul Haque
on 12 May 2020
don't get it...can you please where exactly?
Fazlul Haque
on 12 May 2020
thanks brother, I get it now. I should've put the error check at the beginning
Hari Kiran Tirumaladasu
on 13 May 2020
Edited: Hari Kiran Tirumaladasu
on 15 May 2020
For people who are stuck with this problem, here's a simple and short solution by me. It works!!
CODE
function valid = valid_date(y,m,d)
% To check whether the inputs are scalar and correct
if (isscalar(y) && y > 0 && y ~= 0 ) && (isscalar(m) && m > 0 && m <= 12) && (isscalar(d) && d > 0 && d <= 31)
valid = true;
else
valid = false;
return
end
% To check for Leap Year
if((mod(y,4) == 0 && mod(y,100) ~= 0) || mod(y,400) == 0) && (m == 2 && d <= 29)
valid = true;
% Check for month of February
elseif (m == 2 && d <= 28)
valid = true;
% Check for remaining months
elseif (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) && (d <= 31)
valid = true;
elseif (m == 4 || m == 6 || m == 9 || m == 11) && (d <= 30)
valid = true;
else
valid = false;
end
2 Comments
Walter Roberson
on 15 May 2020
In your first if you test d>0 . Why do you re-test that in your second if ?
Hari Kiran Tirumaladasu
on 15 May 2020
Edited: Hari Kiran Tirumaladasu
on 15 May 2020
Hi Walter, yeah, that wasn't necessary. I edited the code. Thanks!
Sumit Kumar Sharma
on 24 May 2020
Edited: Sumit Kumar Sharma
on 24 May 2020
%% I think this might help
function valid=valid_date(y,m,d)
if isscalar(y) && y>0 && fix(y)==y && isscalar(m) && m<=12 && m>0 && fix(m)==m && isscalar(d) && d>0 && fix(d)==d
x=leap_year(y);
if any(m==[1 3 5 7 8 10 12]) && d<=31
valid=true;
elseif any(m==[4 6 9 11]) && d<=30
valid=true;
elseif m==2 && d<=(28+x)
valid=true;
else
valid=false;
end
else
valid=false;
end
function z= leap_year(c)
if mod(c,4)==0
z=true;
if mod(c,100)==0
z=false;
if mod(c,400)==0
z=true;
end
end
else
z=false;
end
Eshwar Raja Sayinathababu
on 30 Jul 2020
function [valid] = valid_date(year,month,day)
leap_year = 0;
if nargin < 3
valid = false;
end
if (nargin == 3)
if ~isscalar(year) || year < 1 || year ~= fix(year)
valid=false;
return;
end
if ~isscalar(month) || month < 1 || month ~= fix(month)
valid=false;
return;
end
if ~isscalar(day) || day < 1 || day ~= fix(day)
valid=false;
return;
end
end
if ((year == 0) || (month == 0) || (day == 0))
valid = false;
return;
elseif (((isscalar(year)) || (isscalar(month)) || (isscalar(month))) == 0)
valid = false;
return;
elseif (rem(year,4) == 0)
if ((rem(year,100) == 0))
if (rem(year,400)==0)
leap_year = 1;
end
else
leap_year = 1;
end
end
if leap_year == 1
if (month == 1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
if (day > 31)
valid = false;
else
valid = true;
end
elseif (month == 4 || month==6 || month==9 || month==11)
if (day > 30)
valid = false;
else
valid = true;
end
elseif (month == 2)
if (day >29)
valid = false;
else
valid = true;
end
else
valid = false;
end
else
if (month == 1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
if (day > 31)
valid = false;
else
valid = true;
end
elseif (month == 4 || month==6 || month==9 || month==11)
if (day > 30)
valid = false;
else
valid = true;
end
elseif (month == 2)
if (day >28)
valid = false;
else
valid = true;
end
else valid = false;
end
end
end
% This code will work
1 Comment
Rik
on 30 Jul 2020
This code may indeed work, but why did you decide to post it?
Also, why are you testing if the input is 0? If it is smaller than 1 the code will already return false before.
And why did you copy-paste the code for the leap year switch? Why don't you put an if in there only for February? This code is relatively simple, but for more complex code you will have trouble finding all the places to correct a bug. Use code only once. You could even do that for your input validation:
if nargin < 3
valid = false;
end
if (nargin == 3)
if ~isscalar(year) || year < 1 || year ~= fix(year)
valid=false;
return;
end
if ~isscalar(month) || month < 1 || month ~= fix(month)
valid=false;
return;
end
if ~isscalar(day) || day < 1 || day ~= fix(day)
valid=false;
return;
end
end
or:
if nargin==3
for item={year,month,day}
item=item{1};
if ~isscalar(item) || item<1 || item~=fix(item)
valid=false;return
end
end
else
valid=false;return
end
Divya Prasad Singhdev
on 17 Aug 2020
function valid = valid_date (year, month, day)
if isscalar(year)==true && year>0 && isscalar(month)==true && month>0 && month<=12 && isscalar(day)==true && day>0 && day<32
%for leap year, feb = 29days
if (month == 2)
%we need to check whether the year is a centurial leap year or not
if ( mod(year,4) == 0 )
%since every year that is divisible by 4 is not a leap year, we need to check this
if (mod(year,100) == 0) && (mod(year,400) == 0)
%that is the centurial year is a leap year
if day <30
valid = true;
else
valid = false;
end
% since all the centurial years are not leap year we need to check the days
elseif (mod(year,100) == 0 ) && (mod(year,400) ~= 0 )
%that is the centurial year is not a leap year
if day <29
valid = true;
else
valid = false;
end
elseif day < 30 %any other year divisible by 4 which is not a centurial year is a leap year so it should have days < 30
valid = true;
else
valid = false;
end
elseif day <29
valid = true;
else
valid = false;
end
%since the rest of the months are not affected by the leap year
elseif any(month == [1,3,5,7,8,10,12] )
if day <32
valid = true;
else
valid = false;
end
elseif any(month == [4,6,9,11] )
if day <31
valid = true;
else
valid = false;
end
else
valid = false;
end
else
valid = false
end
end
1 Comment
Jan
on 18 Aug 2020
Some hints: if isscalar(year)==true does exactly the same as if isscalar(year). isscalar replies a logical value and comparing it with true replies the same logical value.
You can save a lot of lines, if you move the repeated line valid = false; to the top. Then:
function valid = valid_date (year, month, day)
valid = false;
if isscalar(year) && year>0 && isscalar(month) && month>0 && month<=12 && ...
isscalar(day) && day>0 && day<32
%for leap year, feb = 29days
if (month == 2)
%we need to check whether the year is a centurial leap year or not
if ( mod(year,4) == 0 )
%since every year that is divisible by 4 is not a leap year, we need to check this
if (mod(year,100) == 0) && (mod(year,400) == 0)
%that is the centurial year is a leap year
if day <30
valid = true;
end
% since all the centurial years are not leap year we need to check the days
elseif (mod(year,100) == 0 ) && (mod(year,400) ~= 0 )
%that is the centurial year is not a leap year
if day <29
valid = true;
end
elseif day < 30 %any other year divisible by 4 which is not a centurial year is a leap year so it should have days < 30
valid = true;
end
elseif day <29
valid = true;
end
%since the rest of the months are not affected by the leap year
elseif any(month == [1,3,5,7,8,10,12] )
if day <32
valid = true;
end
elseif any(month == [4,6,9,11] )
if day <31
valid = true;
end
end
end
end
Now the code is a little bit more clear. You can see e.g. this:
if ( mod(year,4) == 0 )
% ^^^^^^^^^^^^^^^^
if (mod(year,100) == 0) && (mod(year,400) == 0)
% ^^^^^^^^^^^^^^^^^^ repeated
if day <30
valid = true;
end
elseif (mod(year,100) == 0 ) && (mod(year,400) ~= 0 )
% ^^^^^^^^^^^^^^^^^^ impossible
While the condition on the top guarantees, that mod(year, 400) == 0, the second IF condition repeats the same test and the third cannot be true.
It would be easier to perfrom the check for a leap year in one step:
if (month == 2)
if (~mod(year, 4) && mod(year, 100) || ~mod(year, 400)) % This is a leap year
valid = (day < 30);
else
valid = (day < 29);
end
else ...
Note that valid = (day < 30) is shorter than:
if (day < 30)
valid = true;
end
Dwight Celis
on 2 Sep 2020
Edited: Dwight Celis
on 2 Sep 2020
function valid= valid_date(y,m,d)
if isscalar(y) && isscalar(m) && isscalar(d) && y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 %for months with 31 days
if d<=31
valid=true;
else
valid=false;
end
elseif m==4||m==6||m==9||m==11 % for months with 30 days only
if d<=30
valid=true;
else
valid=false;
end
else %for february
if mod(y,4)==0 %conditions for leap years
if mod(y,100)==0
if mod(y,400)==0
if d<=29
valid=true;
else
valid=false;
end
else
if d<=28
valid=true;
else
valid=false;
end
end
else
if d<=29
valid=true;
else
valid=false;
end
end
else
if d<=28 %for non-leap years
valid=true;
else
valid=false;
end
end
end
else
valid=false;
end
9 Comments
Rik
on 2 Sep 2020
Why did you post this answer? It is very similar to already posted solutions. What does this add? What does it teach? Why should it not be deleted?
Dwight Celis
on 4 Sep 2020
how it was written is much more organized and easy to understand for beginners like me. Actually the question posted here is an assignment from an online course. Some answers here are way too advanced, using functions that were not yet discussed in our course. Maybe the person who posted the question will understand this more because we're in the same boat.
Rik
on 4 Sep 2020
What is so advanced about the any function or indexing? See for example this solution. What is difficult to understand there? What is so archane about that?
Dwight Celis
on 5 Sep 2020
As what I have mentioned, some are not yet discussed in our course, and we are not yet allowed to use them. Thank you.
Rik
on 5 Sep 2020
Then maybe you should add a clarification at the top of your answer where you describe which functions you're allowed to use. I also can't really imagine someone will scroll all the way down to your answer because they're not allowed to use the any function (which is very strange to me, why would you disallow such basic Matlab functions?).
Dwight Celis
on 5 Sep 2020
Okay, my bad for not stating it before giving my code. And to be clear, I'm not the one who's disallowing them to use functions outside the coverage of our lesson, I'm just also a student. I don't know why u're making this a big deal. if you want to delete my comment, go delete it (if ever you are authorized to do that). But I believe I'm not violating any rule here. I'm just trying to help dude.
Rik
on 5 Sep 2020
I want to make this forum as useful as possible, that is my goal here.
I do have the required reputation points to delete comments and answers, but I prefer not to use it.
Threads like this tend encourage cheating instead of teaching students the way to figure out the solution themselves. Some people also argue that all homework thread should be closed and complete solution should be deleted. I'm not sure that is the most productive way. I do want to encourage people to really think why they want to post an answer. Will the target audience be likely to see it, or will it only attract attention from a certain user that want to keep the thread somewhat concise?
Dwight Celis
on 5 Sep 2020
Okay I see. You can now delete it. I'm sorry
Let me take the chance to suggest some improvements of the code.
Avoid repeated code. Here you define "valid=false;" 7 times. Compare it with this version, where this line is moved to the top as deafult value. In addition
else
if d<=29
valid=true;
end
end
can be simpliefied by an elseif:
function valid= valid_date(y,m,d)
valid = false;
if isscalar(y) && isscalar(m) && isscalar(d) && y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 %for months with 31 days
if d<=31
valid=true;
end
elseif m==4||m==6||m==9||m==11 % for months with 30 days only
if d<=30
valid=true;
end
else %for february
if mod(y,4)==0 %conditions for leap years
if mod(y,100)==0
if mod(y,400)==0
if d<=29
valid=true;
end
elseif d<=28
valid=true;
end
elseif d<=29
valid=true;
end
elseif d<=28 %for non-leap years
valid=true;
end
end
end
19 lines shorter and easier to read. Now join the leap year detection:
function valid = valid_date(y,m,d)
valid = false;
if isscalar(y) && isscalar(m) && isscalar(d) && ...
y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 % months with 31 days
if d<=31
valid=true;
end
elseif m==4||m==6||m==9||m==11 % months with 30 days only
if d<=30
valid=true;
end
else % February
if (mod(year, 4) == 0 && mod(year, 100) ~= 0) || ...
mod(year, 400) == 0 % A leap year
if d<=29
valid=true;
end
elseif d<=28
valid=true;
end
end
end
Finally remember, that
if d<=29
valid=true;
end
is equivalent to:
valid = (d<=29);
Then:
function valid = valid_date(y,m,d)
valid = false;
if isscalar(y) && isscalar(m) && isscalar(d) && ...
y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 % months with 31 days
valid = (d <= 31);
elseif m==4||m==6||m==9||m==11 % months with 30 days only
valid = (d <= 30);
elseif (mod(year, 4) == 0 && mod(year, 100) ~= 0) || ...
mod(year, 400) == 0 % Februrary in a leap year
valid = (d <= 29);
elseif % Februrary, non-leap year
valid = (d <= 28);
end
end
13 lines (not counting the ... continuation) instead of 48. Note that other solutions check if m,d,y have integer values.
Experienced programmers like Rik see the potential for simplifications directly and after removing the redundancies, the solution is almost the same as other already posted solutions. But of course for beginners this equivalence is not obvious.
Rik's question about the reason of posting this answer is eligible. I'd suggest to edit the answer and add your explanation, that this is a version without any() and indexing methods. Finally, I think reading your answer and the discussion is useful, hopefully for you also.
This question is locked.
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
