Please Help Basics Made Hard

1 Ansicht (letzte 30 Tage)
Radoslav Gagov
Radoslav Gagov am 13 Mär. 2017
Kommentiert: Jan am 10 Dez. 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 Kommentare
Walter Roberson
Walter Roberson am 9 Dez. 2018
... And?
A number of errors have been pointed out in the original code.
Jan
Jan am 10 Dez. 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.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Jan
Jan am 13 Mär. 2017
Bearbeitet: Jan am 13 Mär. 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 Kommentare
Jerry Lee
Jerry Lee am 1 Jun. 2018
Bearbeitet: Jan am 8 Jun. 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 am 8 Jun. 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.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (3)

Govind Mishra
Govind Mishra am 14 Mär. 2018
Bearbeitet: Walter Roberson am 14 Mär. 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 am 7 Jun. 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 Kommentare
Lars Wolff
Lars Wolff am 8 Jun. 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 am 8 Jun. 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.

Melden Sie sich an, um zu kommentieren.


Duddela Sai Prashanth
Duddela Sai Prashanth am 23 Sep. 2018
Bearbeitet: Duddela Sai Prashanth am 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 Kommentar
Jan
Jan am 24 Sep. 2018
Bearbeitet: Jan am 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.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Dates and Time finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by