good coding for research

Post on 11-Jul-2015

150 Views

Category:

Education

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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