how can i solve this ,can anyone provide me with code? whats wrong with my code ?

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

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.
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.
i also did that ,its giving some kind of error
Error in solution Line: 20 Column: 5
At least one END is missing: the statement may begin here.
can anyone copy this code and try to run it with
valid=valid_date(2018, 4, 1)
and find the error ,please
let me tell you the true story ,i am doing a course from coursera and this is the question from one of its assignment
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.
its a copy code from someone else ,and i dont understand [anything] from it ,so please guys help me with this
ar i dont know as i said i copied it from some where else
asad's answer moved here
its giving some error about atleast one end is missing ,
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.
Error in solution Line: 19 Column: 5
At least one END is missing: the statement may begin here.
code is same AS above ,i followed your instructon about the bracket
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.
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).
forget everything can anyone tell whats he is asking for ,what its has to do with year divisible by 4,check the example in the question read it .
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.
inputs
valid=valid_date(2018,4,1)
this code above is not mine ,i copied it from matlab answer ,someone else was also facing the same problem ,its not about runing the code its about a proper code so that your answer gets accepted in assignment ,can you guys tell me a new approuch towards the question?
IN QUESTION IT SAYS every year that is divisible 4 and 400 are leap year ,how should i write this in function give an example ,i think code is of like max 14 lines
By the way, 9 lines are enough (including the function and end lines).
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
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;
@Aman Gupta: There is no need to declare the variables as persistent.
@Mohd Sharique Khan: Please post answers in the section for answers.
Can anyone explain how nested if exactly works to calculate leap year in @Mohd Shafique Khan answer
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.)
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:
  1. ((mod(year,100)==0) && (mod(year,400)~=0))
  2. (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

okay now i am really confused ,jan just tell me which code to write ,so that i just copy it ,damn my eyes are hurting , darn matlab .
jan ,its confusing .just write me the code from A TO Z in order ,please .i will pray for you, for a good future lol
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.
i live in a place where i cant even ask anyone for help ,i appreciate your help jan ,i have completed almost 20 assignment own my own ,the only reason i am here is because i am facing problem and i dont have anyone to help me ,matlab is something new for me ,its hard for in getting it ,you are seeing things with your own perspective ,its easy for you not for me ,i am trying but i need help.
jan i tried your code its giving answer for only one question out of six ,thats what i call confusion ,thank you.
@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.
oleksandr is not working for only two questions and if kindly tell me what changes should i make in his code will be beneficial for me ,i dont like to brag but i am in need ,and if you say about learning ,jan everyone has its own ways of learning things ,i will learn after sucessful out .as i said i did other assignment all by myself ,you will not see any other question by me in this forum .just tell me what changes should i make in oleksandr code and where ,explain me easily plz
code of oleksandr is not giving desire answer for two inputs
the last day of every month and random dates .
@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.
i am moving forward doing other assignments by myself ,jan i will do this one in the end ,because it made me stressful ,thanks for the help everyone ,i will be back soon lol we will continue from here ,thanks guys much love to you all .if you guys want to follow me on instagram its (asadjaffar) guy with black wavy hair ,black jacket ,folllow me lol.
+1 your second version is a very tidy and compact use of MATLAB.
@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.
hi @jan i am back ,i have completed all my assignments ,and now i am back to this on .how are you jan?
I'm fine, asad jaffar. Do the posted solutions work for you now?
Chech Joseph about 3 hours ago
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
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
@jan ur 1st code is way better than elseif one i tried previously. Thanks.
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

this code is still not giving the desire answer for two question out of six.
last day of every month and random data
valid_date(2021,11,31)
@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: Your code worked correctly already, I just simplified it a little bit. This looks nicer and shorter code is less prone to typos.
can anyone please send me the correct and exact code please
@samhitha sree: Seriously? You find several working codes in this thread already. Just copy&paste them.
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

bro can you copy my code from the question with the changes in it ?
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.
jan i am so exhausted ,its been 14 hourse since i am stuck in it ,its my 3rd code for this.
@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.
jan code is runing without any errors but not giving the required answer for the question in assignment
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.
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...
i dont understand ,well guys i am doing a course "introduction to matlab' so definitely i am learning it for the first time ,help me out .i am getting agitated now ,my code is running but it is not giving desire results .
it is giving correct answer for only' non leap years '
check coursera ,course introduction to matlab ,week 6 ,last assignment .
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?
hayes assignment generate random non leap years by itself own ,hayes can you kindly to coursera and search for intorduction to matlab and enroll in course its free and then go diretly to week 6 ,open last assignment of week 6 you will understand better then ,about inputs and question.
Have you tried renaming the variable isvalid to valid?
after converting isvalid to valid ,code still run,and now out of 6, 2 are running.
1-the last day of month
2-random non leap year
rest
1-various input
2-non scalar
3-random year
4-random dates
note :this are inputs which assignment generate randomly when we run the code
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...
i agree it should be inside but what should i do then? should i remove the end after the input condition check?
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.
@asad: If you post the code as text and not as screen shot, it is much easier to suggest an improvement.
in question its says if code has valid inputs return true otherwise false so what about
year 4
month 44
day 38
it should be false but there is no code for this check in my code jan ???
jan as i said i cant copy the code it does not allow me to do it,and its the same code you told me to write it down ,jan go to corsera and go to introduction to matlab course ,then go to week 6 last assignment its free and write the code there and run ,you will exactly come to know what problem i am facing if you succed it in running it and got your code acccepted by
walter i know what you said and i followed jan ,now there is no problem of end .its running but out put if not which i need ,i told you guys to go to corsera website and search for introduction to matlab then go to week 6 ,its last assignment of week 6 ,solve it then you guys will know whats the main problem with code ,i know you guys are helping but there are a lot of confusion going on here
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
  1. validate that the inputs are positive integer scalars, and that month number is not too much, and return false if they are not
  2. assignment of number of days of month
  3. test for leap year. Assignment of new value to number of days for february if so.
  4. 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
  5. otherwise return false
okay i will try it tomorrow ,its night here ,i am going to sleep.
i am giving up , i have tried all ofyou guys code ,they all run but dont give desire result,i have done a lot of assignment but this one is confusing as hell.
any last hope???
Please did you passed assignment please help me please send me code
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

(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 ?
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

Could you give an example of a year that could pass the year>0 test but fail year~=0 ?
why do you have to add 3 ends after 2nd elseif
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
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?
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

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
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
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

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.
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).
It works with me man with any date you want
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.
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.
%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

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.
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.
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

There are two things wrong with this post:
  1. it is not an answer, but a question
  2. 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.
You also are not checking that the inputs are integers.
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

you need to test for scalar before you use && as && is only for scalars
don't get it...can you please where exactly?
thanks brother, I get it now. I should've put the error check at the beginning
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

In your first if you test d>0 . Why do you re-test that in your second if ?
Hi Walter, yeah, that wasn't necessary. I edited the code. Thanks!
%% 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
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

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
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

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
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

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?
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.
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?
As what I have mentioned, some are not yet discussed in our course, and we are not yet allowed to use them. Thank you.
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?).
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.
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?
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

Asked:

on 28 Mar 2019

Locked:

on 30 Oct 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!