Tạo một hàm có quá nhiều input dễ dẫn đến nhầm lẫn không đáng có. Sẽ ra sao nếu bạn có thể quyết định thêm hay không các arguments chỉ bằng việc gọi tên chúng và gán giá trị kiểu func('ip1',val1,'ip2',val2)
? inputParser trong matlab sẽ giúp bạn làm điềm đó.
inputParser là gì?
Đây là một object trong matlab giúp bạn quản lý được các tham số đầu vào của một function tự tạo. Bạn có thể tự định nghĩa các tham số cần thiết cho hàm kèm theo tên gọi của chúng để mỗi khi cần sử dụng thì chỉ việc điền tên chúng vào trong hàm là được. Bạn không cần phải liệt kê tất cả các tham số cho dù cần chúng hay không.
Thông thường một hàm tự định nghĩa sẽ có cấu trúc như sau:
func(arg0,arg1,arg2,arg3,...);
Khi sử dụng:
func(arg0,arg1,agr2,arg3,...); % phải đầy đủ tất cả tham số
Với inputParser, bạn có thể sử dụng như sau
func(arg0,'arg1',val1,'agr5',val5); % nếu bạn chỉ muốn dùng arg1 và arg5
inputParser giúp được gì?
- Tạo được các arguments do mình tự đặt tên kèm theo giá trị mặc định của chúng khi chúng không được gọi tên trong hàm. Ví dụ trong trường hợp trên, các arguments ngoài
arg1
vàarg5
sẽ nhận giá trị mặc định của chúng. - Không quan tâm đến thứ tự nhập các arguments.
- Làm cho hàm khi sử dụng trở nên gọn nhẹ hơn. Thay vì phải nhập n arguments thì chỉ cần nhập đúng 2 argument mình cần như ví dụ ở trên.
Cách tạo và sử dụng
Ví dụ để hiểu
Để cho dễ dàng, chúng ta hãy cùng nhau xây dựng một hàm ve_hinh
với các tham số sau (bạn muốn vẽ hàm số $y=f(x)$ và có thể cả hàm $y=g(x)$ trên trục $Oxy$).
x
(bắt buộc, theo thứ tự): giá trị của các điểm $x$ trên trục $Ox$.f
(bắt buộc, theo thứ tự): giá trị của các điểm $y=f(x)$ trên trục $Oy$.g
(tùy chọn, theo thứ tự): giá trị của các điểm $y=g(x)$ trên trục $Oy$ (giả sử màu của đường này luôn là xanh dương và nét liền).duong
(tùy chọn, không theo thứ tự): loại đường nối các điểm của đồ thị lại:net_lien
(mặc định): đường nét liềnnet_dut
: đường nét đứt dàikhong
: không vẽ đường nối, chỉ vẽ điểm
mau
(tùy chọn, không theo thứ tự): màu sắc của đường $y=f(x)$den
(mặc định): màu đenxanh_la
: xanh ládo
: đỏ
Ví dụ, dưới đây là một số cách khai báo và kết quả:
x = 0:pi/100:2*pi;
f = sin(x);
g = cos(x);
ve_hinh(x,f,'duong','khong');

x = 0:pi/100:2*pi;
f = sin(x);
g = cos(x);
ve_hinh(x,f,g,'mau','do');

Nếu dùng đầy đủ tất cả các tham số:
ve_hinh(x,f,g,'duong','dut_net','mau','xanh_la');
Như bạn có thể thấy trong hàm số, sẽ có 3 đối tượng khác biệt:
- bắt buộc + theo thứ tự (
x
,f
): cái này là tham số buộc bạn phải điền vào trongve_hinh
và buộc phải đúng thứ tự như vậy. Tương ứng với từ khóaaddRequired
(sẽ giải thích bên dưới). - tùy chọn + theo thứ tự (
g
): cái này là tham số không bắt buộc phải điền vàove_hinh
, nếu điền thì nó sẽ xử lý, không điền thì thôi (khi ấy giá trị mặc định của nó sẽ được sử dụng). Tuy nhiên tham số này phải đảm bảo đúng thứ tự như trong định nghĩa hàmve_hinh
(trong trường hợp này, nó phảiđứng thứ 3 ngay saux
vàf
). Tương ứng với từ khóaaddOptional
(sẽ giải thích bên dưới). - tùy chọn + không theo thứ tự (
duong
,mau
): bạn có thể không cần điền khi sử dụng hàm, khi ấy các giá trị mặc định ứng với từng tham số sẽ được chọn. Đặc biệt hơn, bạn không nhất thiết phải điền đúng theo thứ tự như lúc khai báo hàmve_hinh
. Ví dụ bạn có thể khai báomau
trướcduong
hoặc ngược lại điều được. Tương ứng với từ khóaaddParameter
(sẽ giải thích bên dưới).
Đoạn code đầy đủ của hàm ve_hinh
là (chứa trong file ve_hinh.m
).
function ve_hinh(x,f,varargin)
p = inputParser;
addRequired(p,'x'); % giá trị x
addRequired(p,'f'); % giá trị y của f
addOptional(p,'g',[]); % giá trị y của g
addParameter(p,'duong','net_lien',@(s) ismember(s,{'khong','net_lien','net_dut'})); % loại đường
addParameter(p,'mau','den',@(s) ismember(s,{'den','do','xanh_la'})); % màu của đường
parse(p,x,f,varargin{:});
kq = p.Results;
switch kq.duong
case 'khong'
duong = '.';
case 'net_lien'
duong = '-';
case 'net_dut'
duong = '--';
end
switch kq.mau
case 'den'
mau = strcat('k',duong);
case 'do'
mau = strcat('r',duong);
case 'xanh_la'
mau = strcat('g',duong);
end
plot(kq.x,kq.f,mau,'DisplayName','f(x)'); % vẽ đường y=f(x)
if ~isempty(kq.g) % nếu g có trong hàm
hold on
plot(kq.x,kq.g,'b-','DisplayName','g(x)'); % vẽ đường y=g(x)
end
legend('show'); % hiển thị chú thích cho từng đường
end
Cấu trúc
Như trong ví dụ trên, để có thể tạo một inputParser, ta tuân thủ theo cấu trúc sau:
function <output> = <tên-hàm>(<các-tham-số-cố-định>,varargin)
p = inputParser; % khởi tạo inputParser (vào biến p)
% Các tham số BẮT BUỘC phải có, THEO THỨ TỰ, mỗi tham số một dòng
addRequired(p,'<tham-số>',<điều-kiện-cho-tham-số>);
% Các tham số TÙY CHỌN nhưng THEO THỨ TỰ, mỗi tham số một dòng
addOptional(p,'<tham-số>',<giá-trị-mặc-định>,<điều-kiện-cho-tham-số>);
% Các tham số TÙY CHỌN và KHÔNG THEO THỨ TỰ, mỗi tham số một dòng
addParameter(p,'<tham-số>',<giá-trị-mặc-định>,<điều-kiện-cho-tham-số>);
% phân tích
parse(p,<các-tham-số-bắt-buộc>,varargin{:});
% Làm việc với các tham số
p.Results.<tham-số>
end
Giải thích và lưu ý
varargin
: cái này là để matlab biết là bạn đang sử dụng inputParser và tất cả các tham số trước nó đều là bắt buộc.<điều-kiện-cho-tham-số>
: cái này là điều kiện dùng để check xem tham số người dùng nhập vào có đúng hay không. Bạn phải dùng function handle để làm điều này. Có rất nhiều cách để làm cái này, bên dưới là một số gợi ý cơ bản.-
Kiểm tra xem một số có là số dương hay không.
<điều-kiện> = @(x) isnumeric(x) && x>0; % ví dụ khi đưa vào inputParser addOptional(p,'x',@(x) isnumeric(x) && x>0); % hoặc dieu_kien = @(x) isnumeric(x) && x>0; addOptional(p,'x',dieu_kien);
- Kiểm tra có phải là ký tự hay không:
ischar
,isstring
(chuỗi ký tự hay không). - Kiểm tra số người dùng nhập vào có nằm trong các số mà mình cho phép hay không.
@(s) ismember(s,[1,5,7,9]); % dấu ngoặc vuông []
- Kiểm tra xem chữ người dùng nhập có nằm trong các chữ cho phép hay không.
@(s) ismember(s,{'den','do','xanh_la'}); % dấu ngoặc nhọn {}
-
Kiểm tra xem một số có là số dương hay không.
- Ngoại trừ các tham số bắt buộc (
addRequired)
, các tham số tùy chọn đều phải cần có<giá-trị-mặc-định>
để khi người dùng không gọi đến chúng, chúng sẽ tự động sử dụng những giá trị mặc định này.
Nâng cao hơn
Trên đây là những điều cơ bản về inputParser tôi giúp bạn quen và tìm hiểu. Dưới đây là một số tùy chọn nâng cao mà bạn có thể tham khảo thêm
- Cho phép các tham số phân biệt hoa/thường hay không (xem [1])
- “Chơi” với các tham số khi bạn có thể để chúng gần nhau (thậm chí không cần dấu phẩy, khoảng trắng để phân biệt), hoặc dùng chung dấu
''
cho tất cả các tham số,… (xem [4])
Tài liệu tham khảo
[1] MathWorks. Matlab Documentation: inputParser.
[2] Will Hope. Better MATLAB functions with the inputParser class.
[3] Mathworks. Parse Function Inputs.
[4] Tibor Simon. Simple Input Parser.