Effacer les filtres
Effacer les filtres

Please Help Basics Made Hard

2 vues (au cours des 30 derniers jours)
Radoslav Gagov
Radoslav Gagov le 13 Mar 2017
Commenté : Jan le 10 Déc 2018
Hey guys, i am trying to solve this assignemnt. :
Write a function called day_diff that takes four scalar positive integer inputs, month1, day1, month2, day2. These represents the birthdays of two children who were born in 2015. The function returns a positive integer scalar that is equal to the difference between the ages of the two children in days. Make sure to check that the input values are of the correct types and they represent valid dates. If they are erroneous, return -1. An example call to the function would be >> dd = day_diff(1,30,2,1); which would make dd equal 2. You are not allowed to use the built-in function datenum or datetime. Hint: store the number of days in the months of 2015 in a 12-element vector (e.g., 31, 28, 31, 30 …) and use it in a simple formula.
I have figured the Hard part but i have problems how to make it accpent only whole possitve numbers and no matrixes as an input. Here is my code :
function [d] = day_diff( month1,day1,month2,day2 )
M=[31,28,31,30,31,30,31,31,30,31,30,31];
if month1==fix(month1)&&month1==fix(month1) && day1==fix(day1) && day2==fix(day2) && isscalar(month1)&&isscalar(day1)&&isscalar(month2)&&isscalar(day2) && day1>0 && day2 > 0 && month1 <=12 && month1 >= 1 && month2 <=12 && month2 >= 1 && M(month1) >= day1 && M(month2) >= day2
d1 = day1 + sum(M(1:1:month1-1));
d2 = day2 + sum(M(1:1:month2-1));
dd = d2-d1;
if dd <0
d = dd*(-1);
else
d = dd;
end
else d = -1;
end
end
  3 commentaires
Walter Roberson
Walter Roberson le 9 Déc 2018
... And?
A number of errors have been pointed out in the original code.
Jan
Jan le 10 Déc 2018
@himanshu tripathi: I have mentioned 18 month ago, that if month1==fix(month1) && ... will fail, if the inputs are not scalars. Please take the time to read the already posted solutions.
You cannot call this function without inputs.

Connectez-vous pour commenter.

Réponse acceptée

Jan
Jan le 13 Mar 2017
Modifié(e) : Jan le 13 Mar 2017
if month1 == fix(month1) && month1==fix(month1) ...
This fails, if month1 is not scalar, because than the == comparison replies a logical array and this collides with using the && operator. The solution is easy: Check at first if teh inputs are scalars:
% Short-circuting!
if isscalar(m1) && isscalar(d1) && isscalar(m2) && isscalar(m1) && ...
m1 == fix(m1) && m1==fix(m1) && d1==fix(d1) && d2==fix(d2) && ...
d1 > 0 && d2 > 0 && m1 <= 12 && m1 >= 1 && m2 <=12 && m2 >= 1 && ...
M(m1) >= d1 && M(m2) >= d2
The && operator is "lazy": It does not evaluate the 2nd argument, when the first is false already. This is called "short-circuting".
In this order the terms "M(m1)" and "M(m2)" are secure also: m1 and m2 has been tested before to be legal indices: integer values and in the allowed range.
I've used "m1" instead of "month1" here, because this is easier to read an matches into the interface of the forum. It is questionable if "month1" or "m1" is better.
Hint: With dd = abs(d2 - d1); you do not have to care about the sign.
Note: You've shown your code and your own effort and asked almost a specific question. Therefore I post an answer although I assume this is a homework question. By the way: This problem appeared already in the forum.
  7 commentaires
Jerry Lee
Jerry Lee le 1 Juin 2018
Modifié(e) : Jan le 8 Juin 2018
function age_difference_days = day_diff(m1, d1, m2, d2)
Month=[31 28 31 30 31 30 31 31 30 31 30 31];
day1=d1+sum(Month(1:(m1-1)));
day2=d2+sum(Month(1:(m2-1)));
if ~isscalar(m1) || ~isscalar(d1) || ~isscalar(m2) || ~isscalar(d2)
age_difference_days=-1;
elseif m1<1 || d1<1 || m2<1 || d2<1 || m1>12 || d1>31 || m2>12 || d2>31
age_difference_days=-1;
elseif Month(m1) < d1 || Month(m2) < d2
age_difference_days=-1;
elseif m1~=fix(m1) || d1~=fix(d1) || m2~=fix(m2) || d2~=fix(d2)
age_difference_days=-1;
else
age_difference_days=abs(day1-day2);
end
This code works well on the most of the cases.Except for the input which is fraction. For instance, day_diff(2.3,4,5,6). I am wondering about if there is something wrong about
elseif m1~=fix(m1) || d1~=fix(d1) || m2~=fix(m2) || d2~=fix(d2)
age_difference_days=-1;
Thanks for your support.
Jan
Jan le 8 Juin 2018
The line to check that the inputs have integer values ( m1~=fix(m1) ) looks okay. Perhaps m1 ~= abs(fix(m1)) is better. But move it before the Month(m1) < d1 test, because here m1 is used as index already, which fails, if it does not have an integer value.
There is a problem in Month(m1) < d1, because Month(m1) == d1 is valid also, isn't it? Exclude 0 also.

Connectez-vous pour commenter.

Plus de réponses (3)

Govind Mishra
Govind Mishra le 14 Mar 2018
Modifié(e) : Walter Roberson le 14 Mar 2018
You can use round function to get an integer out of float and check if a float present or not.
function dd=day_diff(m1,d1,m2,d2)
num_of_days=[31,28,31,30,31,30,31,31,30,31,30,31];
dd=-1;
mmm1=round(m1);mmm2=round(m2);ddd1=round(d1);ddd2=round(d2);
if(isscalar(d1)&&isscalar(d2)&&isscalar(m1)&&isscalar(m2))
if(d1-ddd1 || d2-ddd2 || m1-mmm1 || m2-mmm2)
dd=-1;
else
if (m1<1||m1>12||m2<1||m2>12)
dd=-1;
else
if(d1>num_of_days(m1) || d2>num_of_days(m2) || d1<1 || d2<1)
dd=-1;
else
dd1=sum(num_of_days(1:m1));
dd1=dd1+d1-num_of_days(m1);
dd2=sum(num_of_days(1:m2));
dd2=dd2+d2-num_of_days(m2);
if(dd1>=dd2)
dd=dd1-dd2;
else
dd=dd2-dd1;
end
end
end
end
end

Lars Wolff
Lars Wolff le 7 Juin 2018
Hi!
I am already again asking why my function will not graded.
My solution:
function [dd] = day_diff(month1, day1, month2, day2)
if (month1 == 2 && day1 >28) || (month2 == 2 && day2 >28)
fprintf('Sorry this data is not correct for the year 2015!\n')
return
end
months = [31 28 31 30 31 30 31 31 30 31 30 31]
if month1 == 1
c1=day1
else
c1 = day1 + sum(months((1:(month1-1))))
end
if month2 == 1
c2 = day2
else
c2 = day2 + sum(months((1:(month2-1))))
end
if c1>=c2
dd=c1-c2
else dd=c2-c1
end
end
Response:
NOTE: the grader will only determine if your
solution for Problem 4 is correct or not.
No score will be given.
Problem 4 (day_diff):
Feedback: Your function performed correctly for argument(s) 1, 30, 2, 1
Feedback: Your function performed correctly for argument(s) 1, 1, 1, 1
Feedback: Your function performed correctly for argument(s) 1, 1, 1, 2
Feedback: Your function performed correctly for argument(s) 1, 2, 1, 1
Feedback: Your function performed correctly for argument(s) 1, 1, 2, 1
Feedback: Your function performed correctly for argument(s) 2, 1, 1, 1
Feedback: Your function performed correctly for argument(s) 1, 31, 2, 1
Feedback: Your function performed correctly for argument(s) 2, 1, 1, 31
Feedback: Your function performed correctly for argument(s) 1, 1, 12, 31
Feedback: Your function performed correctly for argument(s) 2, 1, 3, 1
Feedback: Your function performed correctly for argument(s) 7, 1, 9, 30
Feedback: Your program made an error for argument(s) 2, 29, 1, 22
Your solution is _not_ correct.
Thanks for your help in advance!
  6 commentaires
Lars Wolff
Lars Wolff le 8 Juin 2018
Hi Walter! Thank you for the hint and I apologize for I haven't seen it in the question. Currently I am learning matlab with coursera on my own....
Here is my (long) solution - but now it works!!
:-)
function [dd] = day_diff(month1, day1, month2, day2)
months = [31 28 31 30 31 30 31 31 30 31 30 31]
if month1 == 1
c1=day1
else
c1 = day1 + sum(months((1:(month1-1))))
end
if month2 == 1
c2 = day2
else
c2 = day2 + sum(months((1:(month2-1))))
end
if c1>=c2
dd=c1-c2
else dd=c2-c1
end
if ~isscalar(month1) || ~isscalar(day1) || ~isscalar(month2) || ~isscalar(day2)
dd=-1
elseif((month1 == 2 && day1 >28) || (month2 == 2 && day2 >28))
dd=-1
elseif (((month1 == 1 || month1 == 3 || month1 == 5 || month1 == 7 || month1 == 8 || month1 == 10 || month1 == 12) ) && (day1 > 31))
dd=-1
elseif (((month2 == 1 || month2 == 3 || month2 == 5 || month2 == 7 || month2 == 8 || month2 == 10 || month2 == 12) ) && (day2 > 31))
dd=-1
elseif (((month1 == 4 || month1 == 6 || month1 == 9 || month1 == 11) ) && (day1 > 30))
dd=-1
elseif (((month2 == 4 || month2 == 6 || month2 == 9 || month2 == 11) ) && (day2 > 30))
dd=-1
elseif (month1 < 1 || month1 > 12 || month2 < 1 || month2 > 12 || day1 < 1 || day1 > 31 || day2 < 1 || day2 > 31)
dd=-1
end
if round(month1) ~= month1
dd=-1
elseif round(month2) ~= month2
dd=-1
elseif round(day1) ~= day1
dd=-1
elseif round(day2) ~= day2
dd=-1
end
end
Walter Roberson
Walter Roberson le 8 Juin 2018
Hint:
days_in_month = [31 28 31 30 31 30 31 31 30 31 30 31]
day1 > days_in_month(month1)
Also hint: watch out for negative numbers.

Connectez-vous pour commenter.


Duddela Sai Prashanth
Duddela Sai Prashanth le 23 Sep 2018
Modifié(e) : Duddela Sai Prashanth le 23 Sep 2018
%This will work for sure.. Tested on different test cases
function age = day_diff(m1,d1,m2,d2)
m = [31 28 31 30 31 30 31 31 30 31 30 31];
if isscalar(m1) && isscalar(m2) && isscalar(d1) && isscalar(d2)
if m1 == 0 || m2 == 0 || d1 == 0 || d2 == 0
age = -1;
elseif m1 > 0 && d1 > 0 && m2 > 0 && d2 > 0 && m1 <= 31 && d1 <=31 && m2 <=31 && d2 <=31
M2=fix(m2); D2 = fix(d2);
M1=fix(m1); D1 = fix(d1);
if M2 == m2 && M1 == m1 && D2 == d2 && D1==d1
Month2 = m(1:m2-1);
Month1 = m(1:m1-1);
Month2 = sum(Month2);
Month1 = sum(Month1);
days2 = Month2 + d2;
days1 = Month1 + d1;
test2 = m(m2) - d2;
test1 = m(m1) - d1;
if test2<0 || test1<0
age = -1;
else
age = (days2-days1)^2;
age = sqrt(age);
end
else
age = -1;
end
else
age = -1;
end
else
age = -1;
end
  1 commentaire
Jan
Jan le 24 Sep 2018
Modifié(e) : Jan le 24 Sep 2018
You can simplify the code by removing repeated code: Set age=-1 once at the beginning and redefine it only if all checks are satisfied.
"m1 <= 31" and "m2 <=31" is not correct: The maximum value of the month is 12, not 31.
function age = day_diff(m1,d1,m2,d2)
age = -1;
m = [31 28 31 30 31 30 31 31 30 31 30 31];
if isscalar(m1) && isscalar(m2) && isscalar(d1) && isscalar(d2)
if m1 > 0 && d1 > 0 && m2 > 0 && d2 > 0 && ...
m1 <= 12 && d1 <= 31 && m2 <= 12 && d2 <= 31
if fix(m2) == m2 && fix(m1) == m1 && ...
fix(d1) == d2 && fix(d1) == d1
if m(m1) >= d1 && m(m2) >= d2
days1 = sum(m(1:m1-1)) + d1;
days2 = sum(m(1:m2-1)) + d2;
age = abs(days2 - days1);
end
end
end
For scalars abs(a-b) is easier than sqrt((a-b)^2). If a temporary variable occurs once only, it might be simpler to use the formula directly.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Audio Processing Algorithm Design dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by