在Matlab中验证两个相关输入的最佳实践
我有一个关于在具有多个输入的Matlab函数中进行输入验证的最佳实践的问题。这有点哲学。我在论坛中四处看了一下,我还没有看到这方面的全面讨论。我关心验证条件涉及两个或更多输入变量的情况。这是一个例子。在Matlab中验证两个相关输入的最佳实践
假设我用两个输入a和b编写函数。我知道输入必须满足条件
a > 0
和b > 0
。
如果我想验证这些投入,我通常会写这样的功能(只用于说明目的,函数功能并不重要):
% My function
function [result] = myLogSum(a,b)
% Create an input parser
p = inputParser;
% Add required inputs with validation
isPositive = @(x) all(x>0);
addRequired(p, 'a', isPositive);
addRequired(p, 'b', isPositive);
% Parse the inputs
parse(p,a,b);
% Calculate the log sum
result = log(a) + log(b);
end
但现在假设A和B是阵列,并且我还需要检查它们是否具有相同的尺寸:
all(size(a) == size(b)) == true
。
有没有办法处理输入解析器的这种情况?如果不是,处理这个问题的最好方法是什么?
我可以想出四个解决方案,但我无法弄清楚哪一个最好。
1)我是否应该在表单{a,b}
的单个输入单元格数组变量sumInput
中填写a和b,然后为单元格数组写入自定义验证函数?这很好,但我不知道是否总是把输入结合在一起的好习惯。这里能够写myLogSum(a,b)
而不是myLogSum(sumInput)
似乎很自然。
2),或在这种情况下,我应该写在函数中输入验证的这一部分,即修改上面的代码是这样的:
% My function
function [result] = myLogSum(a,b)
% Create an input parser
p = inputParser;
% Add required inputs with validation
isPositive = @(x) all(x>0);
addRequired(p, 'a', isPositive);
addRequired(p, 'b', isPositive);
% Parse the inputs
parse(p,a,b);
% Check that the input arrays have the same size
if ~all(size(a)==size(b))
message = 'The arrays a and b must have the same size.';
error(message);
end
% Calculate the log sum
result = log(a) + log(b);
end
这是一件好事,但它使验证一个有点不均匀和不美观,因为现在我的输入A和b都以不同的方式和不同的原因验证两次。
3)我是不是应该放弃对输入解析器和只写我自己的验证功能,在这里建议:
Best practice when validating input in MATLAB
但是我很喜欢输入解析器,因为它是一种巧妙的方法管理选项。
4)我可以只让Matlab的自行处理错误在程序到达最后一行result = log(a) + log(b)
和数组大小不匹配。但不知何故,我觉得像这样的要价,从长远来看麻烦。
如果你有在Matlab中的经验,只是让我知道你在想什么是最强大和最全面的验证策略,当两个输入相关。
本
有什么可调用parse
一次,然后添加新的输入,并再次调用parse
阻止你 - 此时,您可以使用您的验证功能之前解析值(S)。validateattributes
函数在这里用于构建具有多个条件的验证函数。例如:
% My function
function [result] = myLogSum(a,b)
% Create an input parser
p = inputParser;
% Add required inputs with validation
addRequired(p, 'a', @(x) validateattributes(x, {'numeric'}, {'>', 0}));
% Check the first input was valid
p.parse(a);
addRequired(p, 'b', @(x) validateattributes(x, {'numeric'}, {'>', 0, 'size', size(a)}));
% Parse the inputs
p.parse(a,b);
% Calculate the log sum
result = log(a) + log(b);
end
validateattributes
也产生合理的解释错误信息给你:
>> myLogSum(30, 40)
ans =
7.0901
>> myLogSum([30 20], 40)
Error using myLogSum (line 12)
The value of 'b' is invalid. Expected input to be of size 1x2 when it is
actually size 1x1.
>> myLogSum([30 20], [40 1])
ans =
7.0901 2.9957
>> myLogSum([30 20], [40 -1])
Error using myLogSum (line 12)
The value of 'b' is invalid. Expected input to be an array with all of the
values > 0.
作为一个趣闻:我最终装箱我自己的“parse_input”功能为我的代码,这也给了默认值等。如果你做得不错(不像我这样做),你可以做一个相对普通的函数,但它的确是你最终修改了每个函数的代码块......这不是一个坏的选择,但是如果你这样做,为输入分析器编写单元测试! –
@AnderBiguri这也是我所做的,但由于不同的原因,我根本不知道输入分析器。我能够在我的大项目中编写一个通用解析器作为一个类,它有更多的类,几乎所有的类都使用它。不难携带默认值并处理无序列表。 – Yvon