Good Coding For Research-MATLAB ‘GOOD’ Script-K. Harada(@sousoumt)自己紹介略
112年11月26日月曜日
読者前提
MATLABを使用している
コードの書き方について学んだ経験がない
原田注:資料内では「研究のために」とありますが、研究者以外でも役に立つよう汎用的な資料にしているつもりです。
それぞれ「~のために」を読み替えてください。212年11月26日月曜日
良いコードを書こう
312年11月26日月曜日
充実した研究のために良いコードを書こう
412年11月26日月曜日
無駄はないか?
512年11月26日月曜日
無駄なコーディングしていませんか?
無駄なチュートリアルしていませんか?
612年11月26日月曜日
チュートリアルにおける理想
•教える側
•コード見てね!とだけ伝えたい。
•教わる側
•より短時間でより正確に知りたい。
コードの読みやすさが重要!「動けば良い」は全然ダメ
712年11月26日月曜日
コードの可読性を高める
812年11月26日月曜日
良いコード≒可読性が高い
912年11月26日月曜日
やっつけで可読性の低いコードを書く
コード内に情報が不足
バグ発見時修正が困難
コード改良に時間を要する
研究に割く時間が減る
研究の質が低下する
1012年11月26日月曜日
整理された可読性の高いコードを書く
コード内に情報が足る
バグ発見時修正が容易
コード改良が短時間で済む
研究に割く時間が増える
研究の質が向上する
1112年11月26日月曜日
可読性の高いコードを書き研究に時間を使おう
1212年11月26日月曜日
Good Coding For Research-MATLAB ‘GOOD’ Script-K. Harada
1312年11月26日月曜日
スクリプトと関数を切り分ける
登場順を意識する
名前に情報を詰め込む
コメントを大事に使う
ゴミを残さない
1412年11月26日月曜日
スクリプトと関数を切り分ける
登場順を意識する
名前に情報を詰め込む
コメントを大事に使う
ゴミを残さない
1512年11月26日月曜日
実行可能?ファイル名で区別する
大枠から書く
関数にはin-outの記述を
スクリプトの究極は一読可能!
さらに切り分ける
スクリプトと関数を切り分ける
原田注:以降の資料では、左が悪い例、右が良い例として記載しています。
1612年11月26日月曜日
実行可能?ファイル名で区別する
convertNsn2Mat_BATCH.mconvertNsn2Mat.m
convertNsn2Mat2.mconvertNsn2Mat.m
convertNsn2Mat_func.mconvert.m
1712年11月26日月曜日
大枠から書く
処理1
処理1処理2
処理1処理2処理3
% 処理1% 処理2% 処理3
% 処理1処理1
% 処理2% 処理3
% 処理1処理1
% 処理2処理2
% 処理3
1812年11月26日月曜日
関数にはin-outの記述を
function [w w_matrix] = som_train_with_scale_parameter(data_matrix, num_cell, N_0)
som_train_with_scale_parameter.m
コメント何もなし
function [w w_matrix] = som_train_with_scale_parameter(data_matrix, num_cell, N_0)% Train with scale parameters.% Input:% data_matrix - ****% num_cell - ****% N_0 - ****% Output:% w - ****% w_matrix - ****
1912年11月26日月曜日
スクリプトの究極は一読可能!for i=1:10 for j=1:20 if data{i,j}~=NaN if D.label{j} ~= P.Num{i} fprintf(‘num ne label’); : else if D.roi{j} == NaN error(‘roi not found’); end end endend
ロジック解読が必要
runs = 1:10;channels = 1:20;
% Check Valuesif ~checkArgs(runs, channels, D, P) error(‘format error.’);end
ロジック解読が不要
2012年11月26日月曜日
さらに切り分ける
calc***:gcaxlabel(***);ylabel($$$);
_BATCHに読み飛ばせる部分がある
_BATCHには本質が残る
convertNsn2Mat_BATCH.mcalc***:showGraph;
convertNsn2Mat_BATCH.m
showGraph.mgcaxlabel(***);ylabel($$$);
2112年11月26日月曜日
スクリプトと関数を切り分ける
登場順を意識する
名前に情報を詰め込む
コメントを大事に使う
ゴミを残さない
2212年11月26日月曜日
先頭の情報は最も大事
混ぜるな危険!スクラッチブルに
終わったのか?done出力
更新は誰が?いつ?日付とauthor
登場順を意識する
2312年11月26日月曜日
先頭の情報は最も大事
%function [w w_matrix] = convertMat2Nsn( data_matrix, num_cell, N_0)
if exist(‘abc.mat’):end
convertMat2Nsn_BATCH.m
スクリプト?関数?引数に必要なもの?clearが無かったら?
% Convert Mat to Nsn file.% 1 : check Mat file existing% 2 : check Mat format.% 3 : convert.
convertMat2Nsn_BATCH.m
続きの内容を容易に追える
2412年11月26日月曜日
混ぜるな危険!スクラッチブルに
for kk=1:20 data=load([‘svsv/fmri/data/’ kk]); resA{kk}=calcA(data);end
num = 5;calcB(resA,num);
処理とパラメータが混在 処理とパラメータが別
num=5kkMax=20
for kk=1:kkMax data=load([‘sv/fmri/data/’ kk]); resA{kk}=calcA(data);endcalcB(resA,num);
2512年11月26日月曜日
終わったのか? done出力
終わったのか不明 Doneと出力されたら終了mfilenameも有効
num=5kkMax=20
for kk=1:kkMax data=load([‘sv/fmri/data/’ kk]); resA{kk}=calcA(data);endcalcB(resA,num);
num=5kkMax=20
for kk=1:kkMax data=load([‘sv/fmri/data/’ kk]); resA{kk}=calcA(data);endcalcB(resA,num);fprintf(‘%s Done\n’, mfilename);
2612年11月26日月曜日
更新は誰が?いつ?日付とauthor
いざという時誰に聞けば? 最も良く知る人が把握可能
% Do abc% 1 : check inputs.% 2 : execute abc.
if ~checkArgs(abc) error(‘’);endexec(abc);
% Do abc% 1 : check inputs.% 2 : execute abc.% Modified By: K*** Harada kharada at ****.co.jp 12/09/26
if ~checkArgs(abc) error(‘’);endexec(abc);
2712年11月26日月曜日
スクリプトと関数を切り分ける
登場順を意識する
名前に情報を詰め込む
コメントを大事に使う
ゴミを残さない
2812年11月26日月曜日
名前だけでバグを防ぐ
スコープの意識
難しく考えないで命名規則
tempは誰も喜ばない
名前に情報を詰め込む
2912年11月26日月曜日
名前だけでバグを防ぐ
意味のない変数名はバグに気付きにくい
意味のある変数名はバグに気付きやすい
単数名or複数名の使い分けも良い
for ii = 1:10 for jj = ii:20 if matrix{ii,jj} ~=NaN calcB(6*data{ii,jj}, label{ii,ii}); end endend
for row = 1:10 for col = row:20 if matrix{row, col} ~=NaN oneData = 6*data{row, col}; oneLabel = label{row, row}; calcB(oneData,oneLabel); end endend
3012年11月26日月曜日
for rowCounter = 1:10 for colCounter = rowCounter:20 if ~exist(temp) temp = data{rowC,colC}; end endendclear temp;
for temp=1:20 showNanika;end
for rowCounter = 1:10 for colCounter = rowCounter:20 if ~exist(temp) temp = data{rowC,colC}; end endend
for temp=1:20 showNanika;end
スコープの意識
別の処理部分に影響する可能性
別の処理部分に影響させない
3112年11月26日月曜日
similaritymatrixSIMILARITYMATRIXSimilarityMatrixsimilarity_matrixsm
難しく考えないで命名規則
similarityMatrix : 変数SIMILARITY_MATRIX : 定数SimilarityMatrix : クラス
これ以外であっても、ソース内で統一されていれば可変数名の長さ∝変数のスコープ
3212年11月26日月曜日
temp = calcA();calcB(temp);
tempは誰も喜ばない
calcB(calcA());
or
resultCalcA = calcA();calcB(resultCalcA);clear resultCalcA;
追跡不要
何が入っているのか?再利用されるのか?
要追跡
3312年11月26日月曜日
スクリプトと関数を切り分ける
登場順を意識する
名前に情報を詰め込む
コメントを大事に使う
ゴミを残さない
3412年11月26日月曜日
鉄は熱いうちに、コメントは覚えているうちに
重要なことを足す
疑問、質問、こうなったらバグだ!も書く
パラメータだけコメント化が許される
%%は部分処理と現在地確認に用いる
コメントを大事に使う
3512年11月26日月曜日
鉄は熱いうちに、コメントは覚えているうちに% ParametersA = [1 2 3];
% do XresultX = execX(A);% Test fromresultX = execY(A);% Test to
% do BexecB(resultX);食事後すぐ元通りにできるか?
% ParametersA = [1 2 3];
% do XresultX = execX(A);resultX = execY(A);
% do BexecB(resultX);
インラインでもOK
3612年11月26日月曜日
% Define Parameter AA = [1 2 3];
resultX = execX(A);
% execBexecB(resultX);
重要なことを足す
% ParametersA = [1 2 3];
% do XresultX = execX(A);
% do BexecB(resultX);
コメントだけでコードが読める
見て分かることを書いてしまう必要なことが抜けている
3712年11月26日月曜日
疑問、質問、こうなったらバグだ!も書く% ParametersA = [1 2 3];
% do XresultX = execX(A);% execX失敗時は?% A未定義時はエラー発生
% do BexecB(resultX);execX失敗時は?
% ParametersA = [1 2 3];
% do XresultX = execX(A);
% do BexecB(resultX);
気付きを記載
3812年11月26日月曜日
パラメータだけコメント化が許される
% ParametersA = [1 2 3];% A = {[1 2 3]; [2]; [3]}; %multiple case
% do XresultX = execX(A);
死んでいるパラメータ処理内容にコメント
% ParametersA = [1 2 3];A = {[1 2 3]; [2]; [3]};
% do XresultX = execX(A);%resultX = execY(A); % Cell
設定可能なパラメータを示す処理内容はパラメータにだけ依存させる
3912年11月26日月曜日
%% は部分処理と現在地確認に用いる
%% ParametersA = [1 2 3];% A = {[1 2 3]; [2]; [3]};
%% do XresultX = execX(A);
パラメータの設定確認など部分処理ができない
今どの部分の処理を実行中?
パラメータの設定確認他部分処理が可能
「現在地」を把握可能
% ParametersA = [1 2 3];% A = {[1 2 3]; [2]; [3]};
% do XresultX = execX(A);
4012年11月26日月曜日
スクリプトと関数を切り分ける
登場順を意識する
名前に情報を詰め込む
コメントを大事に使う
ゴミを残さない
4112年11月26日月曜日
変数一覧には重要性の表記がない
一時的変数は即消し
スクリプトが出力の責任を持つ
未使用コードはVCSで積極的に消す
ゴミを残さない
4212年11月26日月曜日
実行後のWorkspace
ii double 8jj double 55matrix cellresultX double 1a logical true
変数一覧には重要性の表記がない
実行後のWorkspace
matrix cell
必要な結果のみを残すsaveで全変数の保存も有効
必要な結果は何?
4312年11月26日月曜日
一時的変数は即消し
tempは残らないtempは残る
[temp data] = calcA();calcB(data);
[temp data] = calcA();calcB(data);clear temp;
4412年11月26日月曜日
スクリプトが出力の責任を持つ
初期化操作close all;clear;で出力に責任を持つ
calcBでエラー&中止時は?
%% ParametersA = [1 2 3];
execX(A)
[temp data] = calcA();ww = fopen(‘test.txt’);calcB(data);fclose(ww);
close all;clear;
%% ParametersA = [1 2 3];:
close all;clear;
4512年11月26日月曜日
未使用コードはVCSで積極的に消す
必要な処理のみ残すVCSを使えばすぐ確認可能
コメントインするとすぐ使えてしまう
% ParametersA = [1 2 3];% A = {[1 2 3]; [2]; [3]};
% do XresultX = execX(A);%resultX = execY(A);%resultX = execZ(A);
% ParametersA = [1 2 3];% A = {[1 2 3]; [2]; [3]};
% do XresultX = execX(A);
4612年11月26日月曜日
スクリプトと関数を切り分ける
登場順を意識する
名前に情報を詰め込む
コメントを大事に使う
ゴミを残さない
まとめ
4712年11月26日月曜日
Top Related