-1

Despite using isscalar, isinteger... the result after running is still true, I still had this test which is incorrect and in relation with Scalar values.

My program:

function valid = valid_date(year, month, day)
[y1 y2] = size(year);
[m1 m2] = size(month);
[d1 d2] = size(day);
if (mod(year,4)==0 && mod(year,100)~=0) || mod(year,400)==0
    is_leap_year = 1;
else   
    is_leap_year = 0;
end 
    if  ~(y1==y2==d1==d2==m1==m2==1)
        valid = false;
    elseif any(month == [1, 3, 5, 7, 8, 10, 12])
        valid = (day >0 && day <= 31) 
        
    elseif any(month == [4, 6, 9, 11])
        valid = day >0 && day <= 30;
                
    elseif month == 2 && is_leap_year == 1
        valid = (day >0 && day <=29);
        
    elseif month == 2 && is_leap_year == 0
        valid = (day >0 && day <=28);
    else
        valid = false;
    end
end

The result after submitting my program, all tests are passed except the one related to scalar values:

Result

Why did my program fail on the non-scalar test?

Wolfie
  • 27,562
  • 7
  • 28
  • 55
  • Doing logical comparisons on floating point numbers is tricky, see [this question](https://stackoverflow.com/q/686439/5211833). – Adriaan Jan 27 '22 at 08:36

2 Answers2

2

The way you're checking for scalars is really not well defined.

~(y1==y2==d1==d2==m1==m2==1)

This chained equivalence check is not the same as checking if all of your variables are equal to 1, consider the following counter-example:

1==0==0==1 % Output: 1

In this case none of your comparison variables should be 0, so you might skirt this issue, but it's still best to avoid it. You're also contending with floating point comparisons which are prone to issues.

You should use isscalar, you say you tried it but didn't show how. Something like this should work:

function valid = valid_date(year, month, day)
    if ~( isscalar(year) && isscalar(month) && isscalar(day) )
        valid = false;
        return
    end
    % ... other code now we know inputs are scalar

end
Wolfie
  • 27,562
  • 7
  • 28
  • 55
  • It's hard to read code in comments, this would have been better suited as an edit to your question where you add this information. However, it doesn't look like you've implemented the check like I showed, I suggested checking if the inputs are scalar first and returning out of the function if not, then implementing all of your other logic. It looks like you've added the condition into the middle of your logic – Wolfie Jan 27 '22 at 10:45
  • thank you so much wolfie, all the tests are passed now thanks to you hamdullah – Chaimae RHANEM Jan 30 '22 at 14:15
  • @chaimae great, consider marking my answer as "accepted" :) – Wolfie Jan 30 '22 at 17:02
  • I don't know how to do it. I am new here ^^ – Chaimae RHANEM Jan 31 '22 at 16:31
  • Click the little tick underneath the voting buttons (top left of my answer) to turn it green – Wolfie Jan 31 '22 at 18:10
1

Thank you so much @Wolfie. The problem is solved. I used what you told me about and put it at the beginning of my function. I show you guys the code, in case you had the same error:

function valid = valid_date(year, month, day)

if ~(isscalar(year) && isscalar(month) && isscalar(day))
        valid = false;
        return
end

if ((mod(year,4)==0 && mod(year,100)~=0) || mod(year,400)==0)
    is_leap_year = 1;
else   
    is_leap_year = 0;
end 


if any(month == [1, 3, 5, 7, 8, 10, 12])
    valid = (day >0 && day <= 31);
        
elseif any(month == [4, 6, 9, 11])
    valid = day >0 && day <= 30;
                
elseif (month == 2 && is_leap_year == 1)
    valid = (day >0 && day <=29);
            
elseif (month == 2 && is_leap_year == 0)
    valid = (day >0 && day <=28);
else
    valid = false;
end

end

Yaaay all the tests are passed lhamdullah!