2013-07-31 4 views
6

私はいくつかの複雑な作業を行うsome_funを持っているとしましょう。matlab関数の冗長性を制御するためのアイデア/ベストプラクティス

function foo = some_complicated_fun(x,y,z,verbosity) 

私はこのコードにプリントをデバッグするのは良いビットを書かれましたが、AVGユーザーは、それが働いている場合は、すべてのことを見ることに興味がないかもしれません。 エラー文(引数が足りないなど)は関係なく出力されます。

機能を書くための私の現在の方法は次のとおりです。

function foo = some_complicated_fun(x,y,z,verbosity) 

(x,y,z,verbosity) = parse_args(x,y,z,verbosity); % parse args, check nargin, etc 

for i=1:5, 

    % whatever  
    % do some work with x,y,z 
    % blah blah 

    if verbosity 
     fprintf('Now on iteration %i\n',i); % basic print 
    end 

    % or, with mutiple levels: 
    if verbosity == 1; 
     fprintf('Now on iteration %i\n',i); % basic print 
    end 
    if verbosity == 2; 
     fprintf('x = %f,y = %f,z=%f %i\n',x,y,z); % more information 
    end 

    % do more work 

end 

私はそれのためクラッタコードまでのif文でそれをやって好きではないが、私は他の方法を考えることはできません。 1つのライナーは、より良いと悪いです:

if verbosity; fprintf('Iteration %i\n',i); end 

ベター・ワンライナーが3行以上同じことよりも読みにくくしているので、それは、小さな悪いことだからです。

私が欲しいのは、冗長を制御するためのシンプルで洗練された方法です。

存在しますか?

答えて

1

私は、ログ出力の冗長性を制御するための方法を作成しました。それはまだ終わっていないが、この質問が登場するので、私はそれをアップロード:

This link at Matlab File Exchange.

それは所望のレベルにグローバル出力ログを設定することで動作し、次の形式のメッセージが表示されます:

OUTPUT_LEVEL: function_which_called_message  Your_Message. 

ただし、設定した出力レベルよりも高いメッセージしか出力されません。デフォルトでは、INFOメッセージ以上しか表示しないので、DEBUGおよびVERBOSEメッセージは表示されません。あなたがデバッグメッセージを表示したい場合は、設定:

Output.level(Output.DISP_DEBUG) 

出力方法は次のとおりです。

Output.VERBOSE 
Output.DEBUG 
Output.INFO 
Output.WARNING 
Output.ERROR 

あなたはsprintfまたはfprintfのようOutput.'DESIRED_LEVEL'('message',input_1,input2)を行うことによって、あなたの関数に表示するメッセージを選択しますmatlab形式です。すなわち、Output.INFO('The variable value is %d',variable)。 WARNINGとERRORメッセージについては、識別子も 'PACKAGE:METHOD:ERROR_ID'と指定することができます。その結果、出力はmatlabのwarningerrorの関数になります。すなわち、Output.WARNING('MY_PACKAGE:MY_METHOD:MY_ID','Something wrong happened here!')

利用可能な出力レベルは、次のとおりです。

Output.level(Output.DISP_VERBOSE) % Show all messages 
Output.level(Output.DISP_DEBUG) % Show debug info warning errors 
Output.level(Output.DISP_INFO) % Show info warning errors 
Output.level(Output.DISP_WARNING) % Show warning errors 
Output.level(Output.DISP_MUTE) % Show only errors. 

ます。また、(あなたも現在のログをリセットするためにそれを使用することができます)

Output.place('file_path') 

を使用して、ログファイルへの出力を指定し、ログ・ファイルを置き換えることができます:

Output.place('file_path',true) 

または

をスクリーニングするために、それをリセットここでは0
Output.place(1) 

出力レベルDISP_VERBOSE使用して出力のサンプルです:私が言ったように

>> nilmContainer = NilmFileContainer.newRun('inputFolder','sim_real/','runName','RealHouse','samplesPerFile',60*60*60); 
VERBOSE: getFilesOnFolder    Found 2 files on folder 'data/sim_real/'. They are the following: 
VERBOSE: getFilesOnFolder     [1]:data/sim_real/240AM000.csv 
VERBOSE: getFilesOnFolder     [2]:data/sim_real/240AM001.csv 
DEBUG: NilmFileContainer.setRunName Updating run name to RealHouse_Run5. 
INFO: newRun       Reading file data/sim_real/240AM000.csv. 
VERBOSE: csv_data      Reading samples (Ignored:0,Read:216000,Remaining:2422014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_1-19:12:46-30_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:216000,Read:216000,Remaining:2206014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_2-20:12:45-30_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:432000,Read:216000,Remaining:1990014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_3-21:12:45-30_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:648000,Read:216000,Remaining:1774014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_4-22:12:45-30_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:864000,Read:216000,Remaining:1558014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_5-23:12:45-30_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:1080000,Read:216000,Remaining:1342014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_6-00:12:44-31_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:1296000,Read:216000,Remaining:1126014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_7-01:12:43-31_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:1512000,Read:216000,Remaining:910014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_8-02:12:43-31_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:1728000,Read:216000,Remaining:694014) at file: sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_9-03:12:43-31_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:1944000,Read:216000,Remaining:478014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_10-04:12:42-31_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:2160000,Read:216000,Remaining:262014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_11-05:12:41-31_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:2376000,Read:216000,Remaining:46014) at file: data/sim_real/240AM000.csv. 
DEBUG: addFiles      Writing file 'data/NILM_DATA/RealHouse_Run5/RealHouse_Run5-File_12-06:12:41-31_10_2012.mat' 
VERBOSE: csv_data      Reading samples (Ignored:2592000,Read:46014,Remaining:0) at file: data/sim_real/240AM000.csv. 
VERBOSE: csv_data      Reading samples (Ignored:0,Read:169986,Remaining:2799058) at file: data/sim_real/240AM001.csv. 
INFO: readFile      Found discontinuity while changing from file 'data/sim_real/240AM000.csv' to 'data/sim_real/240AM001.csv'. 

を、それが最終版ではありませんが、私はそれを向上させることができます! x)

+1

これは素晴らしいですね! – Frederick

2

ifステートメントと実際の印刷を含むfprintfを置き換える関数を定義します。また、毎回引数として渡さないように、verbosityglobalという変数として宣言します。

1

これは私がやったことです。

は、私はグローバル変数をしたいということはよく分からない機能(私はそれをまた、vprintfと呼ばれる、より良い名前があります。)

を書いたが、それは考えたのです。あなたは、関数の最後でnested functionとしてあなたvprintf関数を定義することができますフレデリックとルイス・Mendoからの回答の改良として

function vprintf(v,l,varargin) 
% VPRINTF(verbosity, verbosity_level_of_statement,sprintf_style_arguments 
% 
% 
% example: 
% 
% verbosity = 1; 
% vprintf(verbosity,1,'This will print if verbosity is at least 1\n Verbosity = %i\n',verbosity); 

if nargin<3 
    error('not enough arguments'); 
end 
if v>=l % if verbosity level is >= level of this statment 
%  keyboard; 
    fprintf(varargin{:}); 
end 
1

。引き数verbosityにアクセスし、グローバル変数は必要ありません。あなたのコードは次のようになります。

function foo = some_complicated_fun(x,y,z,verbosity) 

[x,y,z,verbosity] = parse_args(x,y,z,verbosity); % parse args, check nargin, etc 

for i=1:5, 

    % whatever  
    % do some work with x,y,z 
    % blah blah 

    vprintf(1,'Now on iteration %i\n',i); % basic print 

    % or, with mutiple levels: 
    vprintf(1,'Now on iteration %i\n',i); % basic print 
    vprintf(2,'x = %f,y = %f,z=%f %i\n',x,y,z); % more information 

    % do more work 
end 

    % time to define vprintf 
    function vprintf(l,varargin) 
    % VPRINTF(verbosity, verbosity_level_of_statement,sprintf_style_arguments 
    % 
    % 
    % example: 
    % 
    % verbosity = 1; 
    % vprintf(1,'This will print if verbosity is at least 1\n Verbosity = %i\n',verbosity); 

    if nargin<2 
     error('not enough arguments'); 
    end 
    if verbosity>=l % if verbosity level is >= level of this statment 
    %  keyboard; 
     fprintf(varargin{:}); 
    end 
end 

ギュンターStruyfは、コメントに記載された保守性の問題を克服するには、[編集] 、あなたはvprintfで永続的な変数でverbosity値を維持し、最初の呼び出しでそれを設定することができます。

function vprintf(vl,varargin) 
% VPRINTF(verbosity); 
% VPRINTF(verbosity_level_of_statement,sprintf_style_arguments); 

persistent verbosity 
if nargin==1 
    verbosity = vl; 
elseif isempty(verbosity) 
    error('verbosity level not set'); 
end 

if verbosity>=vl % if verbosity level is >= level of this statment 
%  keyboard; 
    fprintf(varargin{:}); 
end 

次に、fooで機能を設定し、それ以降のステートメントで使用します。たぶん私はこれをやってみたかったと思います場合vprintf([]);

function foo = some_complicated_fun(x,y,z,verbosity) 

[x,y,z,verbosity] = parse_args(x,y,z,verbosity); % parse args, check nargin, etc 

vprintf(verbosity); 
for i=1:5, 

    % whatever  
    % do some work with x,y,z 
    % blah blah 

    vprintf(1,'Now on iteration %i\n',i); % basic print 

    % or, with mutiple levels: 
    vprintf(1,'Now on iteration %i\n',i); % basic print 
    vprintf(2,'x = %f,y = %f,z=%f %i\n',x,y,z); % more information 

    % do more work 
end 
vprintf([]); 
+0

しかし、それを使用するすべての機能にコピーする必要があります。特にそのネストされた機能で何かを変更する場合は痛みを伴う機能を使用します。 –

+0

@GuntherStruyfそうです。コードベース全体にどれほど普及しているかによって異なります。グローバル変数の代わりに永続変数を使用する別のソリューションを追加しました。 –

0

で終了の値をクリアすることをお勧め、私はlogDebuglogInfologWarninglogErrorなどの機能を持つthisと同様に、Loggerクラスを作成したいです。 (私は実際にはlua hereのためにこれを行っています)。

作成時にログレベルを設定する必要があり、Loggerオブジェクトのスコープで完全な機能と機能にアクセスできます(グローバルスコープの汚染がなく、複数のmファイルで簡単に実装できます)。このクラスの

だから、最終的に使用することは、次のようになります。

%% my fancy script 
% init 
logger = Logger(Logger.LOGDEBUG) 
logger.logDebug('script initialized'); 

% plot some stuff 
logger.logDebug('commencing plot'); 
plot(rand(4)); 
logger.logInfo('fancy script ended'); 
関連する問題