Szukaj…


Uwagi

W tym temacie przedstawiono najlepsze praktyki, których społeczność nauczyła się z czasem.

Trzymaj linie krótkie

Użyj znaku kontynuacji (elipsa) ... aby kontynuować długą instrukcję.

Przykład:

MyFunc( parameter1,parameter2,parameter3,parameter4, parameter5, parameter6,parameter7, parameter8, parameter9)

można zastąpić:

MyFunc( parameter1, ...
        parameter2, ...
        parameter3, ...
        parameter4, ...
        parameter5, ...
        parameter6, ...
        parameter7, ...
        parameter8, ...
        parameter9)

Poprawne wcięcie

Prawidłowe wcięcie nadaje nie tylko estetyczny wygląd, ale także zwiększa czytelność kodu.

Na przykład rozważ następujący kod:

%no need to understand the code, just give it a look
n = 2;
bf = false;
while n>1
for ii = 1:n
for jj = 1:n
if ii+jj>30
bf = true;
break
end
end
if bf
break 
end
end
if bf
break 
end
n = n + 1;
end

Jak widać, musisz dokładnie przyjrzeć się, która pętla i if instrukcje kończą się gdzie.
Dzięki inteligentnemu wcięciu uzyskasz ten wygląd:

n = 2;
bf = false;
while n>1
    for ii = 1:n
        for jj = 1:n
            if ii+jj>30
                bf = true;
                break
            end
        end
        if bf
            break
        end
    end
    if bf
        break
    end
    n = n + 1;
end

To wyraźnie wskazuje początek i koniec instrukcji loop / if .

Możesz wykonać inteligentne wcięcie poprzez:
zaznaczenie całego kodu ( Ctrl + A )
a następnie naciskając Ctrl + I lub klikając SmartIndentIcon z paska edycji. Redaktor

Użyj potwierdzenia

Matlab pozwala na ciche pomijanie niektórych bardzo trywialnych błędów, które mogą spowodować, że błąd zostanie zgłoszony znacznie później w trakcie uruchamiania - utrudniając debugowanie. Jeśli zakładamy coś o zmiennych, zatwierdź go.

function out1 = get_cell_value_at_index(scalar1,cell2)
assert(isscalar(scalar1),'1st input must be a scalar')
assert(iscell(cell2),'2nd input must be a cell array')

assert(numel(cell2) >= scalar1),'2nd input must have more elements than the value of the 1st input')
assert(~isempty(cell2{scalar1}),'2nd input at location is empty')

out1 = cell2{scalar1};

Unikaj pętli

W większości przypadków pętle są drogie obliczeniowo w Matlabie. Twój kod będzie o rząd wielkości szybszy, jeśli użyjesz wektoryzacji. Często sprawia również, że kod jest bardziej modułowy, łatwo modyfikowalny i łatwiejszy do debugowania. Główną wadą jest to, że trzeba poświęcić czas na planowanie struktur danych, a błędy wymiarów są łatwiejsze do znalezienia.

Przykłady

Nie pisz

for t=0:0.1:2*pi
    R(end+1)=cos(t);
end

ale

t=0:0.1:2*pi;
R=cos(t)

Nie pisz

for i=1:n
    for j=1:m
        c(i,j)=a(i)+2*b(j);
    end
end

Ale coś podobnego do

c=repmat(a.',1,m)+2*repmat(b,n,1)

Aby uzyskać więcej informacji, zobacz wektoryzacja

Utwórz unikalną nazwę dla pliku tymczasowego

Podczas kodowania skryptu lub funkcji może się zdarzyć, że jeden lub więcej plików tymczasowych będzie potrzebnych na przykład do przechowywania niektórych danych.

Aby uniknąć zastąpienia istniejącego pliku lub zaciemnienia funkcji MATLAB, można użyć funkcji tymczasowej do wygenerowania unikalnej nazwy pliku tymczasowego w systemowym folderze tymczasowym.

my_temp_file=tempname

Nazwa pliku jest generowana bez rozszerzenia; można go dodać, tempname pożądane rozszerzenie z nazwą wygenerowaną przez tempname

my_temp_file_with_ext=[tempname '.txt']

Lokalizację systemowego folderu tymczasowego można odzyskać, wyrywając funkcję tempdir .

Jeśli podczas wykonywania funkcji / skryptu plik tymczasowy nie jest już potrzebny, można go usunąć za pomocą funkcji delete

Ponieważ delete nie prosi o potwierdzenie, to może być przydatne, aby ustawić on opcję, aby przenieść plik do usunięcia w recycle folderu.

Można to zrobić za pomocą funkcji recyklingu w ten sposób:

recycle('on')

W poniższym przykładzie zaproponowano możliwe użycie funkcji tempname , delete i recycle .

%
% Create some example data
%
theta=0:.1:2*pi;
x=cos(theta);
y=sin(theta);
%
% Generate the temporary filename
%
my_temp_file=[tempname '.mat'];
%
% Split the filename (path, name, extension) and display them in a message box
[tmp_file_path,tmp_file_name, tmp_file_ext]=fileparts(my_temp_file)
uiwait(msgbox(sprintf('Path= %s\nName= %s\nExt= %s', ...
              tmp_file_path,tmp_file_name,tmp_file_ext),'TEMPORARY FILE'))
%
% Save the varaibles in a temporary file
%
save(my_temp_file,'x','y','theta')
%
% Load the varaibles from the temporary file
%
load(my_temp_file)
%
% Set the reclycle option on
%
recycle('on')
%
% Delete the temporary file
%
delete(my_temp_file)

Zastrzeżenie

Tymczasowa nazwa pliku jest generowana przy użyciu metody java.util.UUID.randomUUID ( randomUUID ).

Jeśli MATLAB jest uruchamiany bez JVM, tymczasowa nazwa pliku jest generowana przy użyciu
matlab.internal.timing.timing oparty na liczniku procesora i czasie. W takim przypadku tymczasowa nazwa pliku nie jest gwarantowana.

Użyj sprawdzania poprawności atrybutów

Funkcja validateattributes może być używana do sprawdzania poprawności tablicy względem zestawu specyfikacji

Można go zatem wykorzystać do sprawdzenia poprawności danych wejściowych funkcji.

W poniższym przykładzie funkcja test_validateattributes wymaga trzech danych wejściowych

function test_validateattributes(input_1,input_2,input_3)

Dane wejściowe to:

  • tablica_1:

    • klasa: podwójna
    • rozmiar: [3,2]
    • wartości: elementy nie mogą być NaN
  • char_array:

    • klasa: char
    • wartość: ciąg nie może być pusty
  • tablica_3

    • klasa: podwójna
    • rozmiar: [5 1]
    • wartości: elementy muszą być prawdziwe

Aby sprawdzić poprawność trzech danych wejściowych, funkcję validateattributes można wywołać za pomocą następującej składni:

validateattributes(A,classes,attributes,funcName,varName,argIndex)

gdzie:

  • A to tablica, która ma zostać przeszukana
  • classes : to type tablicy (np. single , double , logical )
  • attributes : to attributes które musi dopasować tablica wejściowa (np. [3,2], size określający rozmiar tablicy, wartość nonnan określająca, że tablica nie będzie mieć wartości NaN)
  • funcName : jest nazwą funkcji, w której odbywa się sprawdzanie poprawności. Ten argument jest używany podczas generowania komunikatu o błędzie (jeśli występuje)
  • varName : to nazwa sprawdzanej tablicy. Ten argument jest używany podczas generowania komunikatu o błędzie (jeśli występuje)
  • argIndex : jest pozycją tablicy inpurt na liście danych wejściowych. Ten argument jest używany podczas generowania komunikatu o błędzie (jeśli występuje)

W przypadku, gdy jedno lub więcej danych wejściowych nie pasuje do specyfikacji, generowany jest komunikat o błędzie.

W przypadku więcej niż jednego nieprawidłowego wejścia sprawdzanie poprawności kończy się, gdy zostanie znalezione pierwsze niedopasowanie.

Jest to function test_validateattributes w której zaimplementowano sprawdzanie poprawności danych wejściowych.

Ponieważ funkcja wymaga trzech danych wejściowych, pierwsze sprawdzenie liczby wprowadzonych danych jest przeprowadzane przy użyciu funkcji nargin .

function test_validateattributes(array_1,char_array_1,array_3)
%
% Check for the number of expected input: if the number of input is less
% than the require, the function exits with an error message
%
if(nargin ~= 3)
   error('Error: TEST_VALIDATEATTRIBUTES requires 3 input, found %d',nargin)
end
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the first input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #1 name (only used in the generation of the error message)
%
input_1_name='array_1';
%
% INPUT #1 position (only used in the generation of the error message)
%
input_1_position=1;
%
% Expected CLASS of the first input MUST BE "double"
%
input_1_class={'double'};
%
% Expected ATTRIBUTES of the first input
%   SIZE: MUST BE [3,2]
%
input_1_size_attribute='size';
input_1_size=[3,2];
%
%   VALUE CHECK: the element MUST BE NOT NaN
%
input_1_value_type='nonnan';
%
% Build the INPUT 1 attributes
%
input_1_attributes={input_1_size_attribute,input_1_size, ...
                    input_1_value_type};
%
% CHECK THE VALIDITY OF THE FIRST INPUT
%
validateattributes(array_1, ...
                   input_1_class,input_1_attributes,'', ...
                   input_1_name,input_1_position);

%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the second input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #1 name (only used in the generation of the error message)
%
input_2_name='char_array_1';
%
% INPUT #2 position (only used in the generation of the error message)
%
input_2_position=2;
%
% Expected CLASS of the first input MUST BE "string"
%
input_2_class={'char'};
%
%   VALUE CHECK: the element must be not NaN
%
input_2_size_attribute='nonempty';
%
% Build the INPUT 2 attributes
%
input_2_attributes={input_2_size_attribute};
%
% CHECK THE VALIDITY OF THE SECOND INPUT
%
validateattributes(char_array_1, ...
                   input_2_class,input_2_attributes,'', ...
                   input_2_name,input_2_position);
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the third input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #3 name (only used in the generation of the error message)
%
input_3_name='array_3';
%
% INPUT #3 position (only used in the generation of the error message)
%
input_3_position=3;
%
% Expected CLASS of the first input MUST BE "double"
%
input_3_class={'double'};
%
% Expected ATTRIBUTES of the first input
%   SIZE: must be [5]
input_3_size_attribute='size';
input_3_size=[5 1];
%   VALUE CHECK: the elements must be real
input_3_value_type='real';
%
% Build the INPUT 3 attributes
%
input_3_attributes={input_3_size_attribute,input_3_size, ...
                    input_3_value_type};
%
% CHECK THE VALIDITY OF THE FIRST INPUT
%
validateattributes(array_3, ...
                   input_3_class,input_3_attributes,'', ...
                   input_3_name,input_3_position);

disp('All the three input are OK')

Poniższego skryptu można użyć do przetestowania wdrożenia procedury sprawdzania poprawności.

Generuje trzy wymagane dane wejściowe i, losowo, czyni je nieważnymi.

%
% Generate the first input
%
n_rows=randi([2 3],1);
n_cols=2;
input_1=randi([20 30],n_rows,n_cols);
%
% Generate the second input
%
if(rand > 0.5)
   input_2='This is a string';
else
   input_2='';
end
%
% Generate the third input
%
input_3=acos(rand(5,1)*1.2);
%
% Call the test_validateattributes function with the above generated input
%
input_1
input_2
input_3
%
test_validateattributes(input_1,input_2,input_3)

Oto kilka przykładów nieprawidłowych danych wejściowych wykrytych przez funkcję validateattributes :

Błędne wejście

input_1 =

    23    22
    26    28

input_2 =

     ''

input_3 =

   0.0000 + 0.4455i
   1.2420 + 0.0000i
   0.4063 + 0.0000i
   1.3424 + 0.0000i
   1.2186 + 0.0000i

Error using test_validateattributes (line 44)
Expected input number 1, array_1, to be of size 3x2 when it is actually
size 2x2.

Błędne wejście

input_1 =

    22    24
    21    25
    26    27

input_2 =

This is a string

input_3 =

   1.1371 + 0.0000i
   0.6528 + 0.0000i
   1.0479 + 0.0000i
   0.0000 + 0.1435i
   0.0316 + 0.0000i

Error using test_validateattributes (line 109)
Expected input number 3, array_3, to be real.

Prawidłowe wejście

input_1 =

    20    25
    25    28
    24    23

input_2 =

This is a string

input_3 =

    0.9696
    1.5279
    1.3581
    0.5234
    0.9665

All the three input are OK

Zablokuj komentarz operatora

Dobrą praktyką jest dodawanie komentarzy opisujących kod. Jest to pomocne dla innych, a nawet dla programisty, gdy zostanie zwrócony później. Pojedynczy wiersz można skomentować za pomocą symbolu % lub skrótu Ctrl+R Aby anulować komentarz do poprzednio komentowanego wiersza, usuń symbol % lub użyj skrótu Crtl+T

Podczas gdy komentowanie bloku kodu można zrobić, dodając symbol % na początku każdej linii, nowsze wersje MATLAB (po 2015a) pozwalają na użycie operatora komentowania bloków %{ code %} . Ten operator zwiększa czytelność kodu. Może być używany zarówno do komentowania kodu, jak i dokumentacji pomocy funkcji. Blok można składać i rozkładać, aby zwiększyć czytelność kodu.

wprowadź opis zdjęcia tutaj

Jak widać operatory %{ i %} muszą pojawiać się same w liniach. Nie umieszczaj żadnego innego tekstu w tych wierszach.

function y = myFunction(x)
%{
myFunction  Binary Singleton Expansion Function
y = myFunction(x) applies the element-by-element binary operation
specified by the function handle FUNC to arrays A and B, with implicit
expansion enabled.
%}

%%  Compute z(x, y) = x.*sin(y) on a grid:
% x = 1:10;
y = x.';

%{
z = zeros(numel(x),numel(y));
for ii=1:numel(x)
    for jj=1:numel(y)
        z(ii,jj) = x(ii)*sin(y(jj));
    end
end
%}

z = bsxfun(@(x, y) x.*sin(y), x, y);
y = y + z;

end


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow