МАТЛАБ: Почему функция не может обработать ошибку при заданном вводе даты? - PullRequest
0 голосов
/ 09 января 2019

Я изучаю MATLAB на Coursera и застрял с этим вопросом:

Напишите функцию с именем day_diff, которая принимает четыре скалярных положительных целочисленных значения, месяц1, день1, месяц2, день2. Они представляют дни рождения двух детей, которые родились в 2015 году. Функция возвращает положительный целочисленный скаляр, который равен разнице в возрасте двух детей в днях. Убедитесь, что входные значения имеют правильные типы и представляют действительные даты. Если они ошибочны, верните -1. Пример вызова функции будет
dd = day_diff(1,30,2,1);
что сделало бы dd равным 2. Вы не можете использовать встроенную функцию datenum или datetime. Подсказка: сохраните количество дней в месяцах 2015 года в векторе из 12 элементов (например, 31, 28, 31, 30 ...) и используйте его в простой формуле.

Несколько случаев проверяются с использованием предварительно созданного кода оценки. Мой код до сих пор:

function answer = day_diff(month1, day1, month2,day2)
    answer = -1;
    days_in_months = [31,28,31,30,31,30,31,31,30,31,30,31]; %days in every month array
    flag1 = days_in_months(month1); %to check if day1 is valid
    flag2 = days_in_months(month2); %to check if day2 is valid
    %Non valid values handing
    if nargin < 4
        error('Must have four arguments');
    end
    if ~isscalar(month1) || month1 < 1 || month1 ~= fix(month1) || month1 > 12
        error('month1 needs to be a positive integer and not greater than 12.');
    end
    if ~isscalar(month2) || month2 < 1 || month2 ~= fix(month2) || month2 > 12        
        error('month2 needs to be a positive integer and not greater than 12.');
    end
    if ~isscalar(day1) || day1 < 1 || day1 ~= fix(day1)|| day1 > flag1        
        error('day1 needs to be a positive integer and a valid date.');
    end
    if ~isscalar(day2) || day2 < 1 || day2 ~= fix(day2)|| day2 > flag2        
        error('day1 needs to be a positive integer and a valid date.');
    end
    %end of error handler
    %to find the age in days
    if (month1 == month2)
        inbetween_days = 0;
        if day1 == day2
            first_last_days = 0;
        elseif day1 < day2
            first_last_days = day2 - day1;
        else
            first_last_days = day1 - day2;
        end
    elseif month1 < month2
            inbetween_days = sum(days_in_months(month1+1:month2-1));
            first_last_days = (days_in_months(month1)-day1) + day2;
        else
            inbetween_days = sum(days_in_months(month2+1:month1-1));
            first_last_days = day1 + (days_in_months(month2)-day2);
    end
     answer = first_last_days +  inbetween_days;
end

пока все хорошо, но когда значение day_diff (2, 29, 1, 22), файл оценки выдает ошибку вместо обработки неправильного предопределенного ввода (день1 равен 29, а максимум равен 28), проблема заключается в как вернуть -1?

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.

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Я бы удалил answer = -1 в первой строке и обработал бы все ошибки в одном блоке if, чтобы избежать ошибок в случаях, которые могут попадать между блоками elseif:

% Non valid values handing:
if (nargin ~= 4) ||...
        ~all([isscalar(month1) isscalar(month2) isscalar(day1) isscalar(day2)]) ||... % only scalars
        any([month1,month2,day1,day2]<1) ||... % all input greater then zero
        any(fix([month1,month2,day1,day2]) ~= [month1,month2,day1,day2]) ||... % all are integers
        any([month1,month2,day1,day2] > [12 12 flag1 flag2]) % all are valid dates
    answer = -1;
    return;
end
% end of error handler

если условие истинно, функция присваивает от -1 до answer и гаснет (на return).

По моему мнению, такой способ обработки ошибок более прост и менее подвержен ошибкам, но я не уверен, что он решит исходную проблему.

Вы также можете удалить оператор return и поместить все остальные функции в блок else, т. Е .:

if (nargin ~= 4) ||... % all the condition...           
    answer = -1;
else
    % all the calculation...
    answer = first_last_days +  inbetween_days;
end
0 голосов
/ 09 января 2019

Да, вы никогда не вернете -1, которое они просили. Удалите сообщения об ошибках, и в этих случаях просто ничего не делайте, и пусть ваш ответ останется -1. Ниже приведено больше строк кода, чем было у вас, и вы можете улучшить его, но это должно пройти тест, который вы провалили

    function answer = day_diff(month1, day1, month2,day2)
    answer = -1;
    days_in_months = [31,28,31,30,31,30,31,31,30,31,30,31]; %days in every month array
    flag1 = days_in_months(month1); %to check if day1 is valid
    flag2 = days_in_months(month2); %to check if day2 is valid
    %Non valid values handing
    if nargin < 4
        answer=-1;

    elseif ~isscalar(month1) || month1 < 1 || month1 ~= fix(month1) || month1 > 12
        answer=-1;
    elseif ~isscalar(month2) || month2 < 1 || month2 ~= fix(month2) || month2 > 12        
        answer=-1;
    elseif ~isscalar(day1) || day1 < 1 || day1 ~= fix(day1)|| day1 > flag1        
        answer=-1;
    elseif ~isscalar(day2) || day2 < 1 || day2 ~= fix(day2)|| day2 > flag2        
        answer=-1;
    %end of error handler
    %to find the age in days
    elseif (month1 == month2)
        inbetween_days = 0;
        if day1 == day2
            first_last_days = 0;
        elseif day1 < day2
            first_last_days = day2 - day1;
        else
            first_last_days = day1 - day2;
        end
        answer = first_last_days +  inbetween_days;
    elseif month1 < month2
            inbetween_days = sum(days_in_months(month1+1:month2-1));
            first_last_days = (days_in_months(month1)-day1) + day2;
            answer = first_last_days +  inbetween_days;
    else
            inbetween_days = sum(days_in_months(month2+1:month1-1));
            first_last_days = day1 + (days_in_months(month2)-day2);
            answer = first_last_days +  inbetween_days;
    end

end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...