MyEnigma

とある自律移動システムエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

MATLAB Programming Style Guidelines 7: Statements

この記事は,

Datatool社のRichard Johnson氏が書いた

"MATLAB Programming Style Guideline"

を自分なりに翻訳したものです.



この文書は

MATLABのコードをより素晴らしいものにするための

多数のコーディング作法について書かれています.



翻訳結果は以下の各リンクから読むことができます.

0. MATLAB Programming Style Guidelines : About This Document - MY ENIGMA

1. MATLAB Programming Style Guidelines : Introduction - MY ENIGMA

2. MATLAB Programming Style Guidelines : Naming Conventions - MY ENIGMA

3. MATLAB Programming Style Guidelines : Constants and Structures - MY ENIGMA

4. MATLAB Programming Style Guidelines : Functions - MY ENIGMA

5. MATLAB Programming Style Guidelines : General - MY ENIGMA

6. MATLAB Programming Style Guidelines : Files and Organization - MY ENIGMA

7. MATLAB Programming Style Guidelines : Statements - MY ENIGMA

8. MATLAB Programming Style Guidelines : Layout, Comments and Documentation - MY ENIGMA



もし,これらの文章に意見や質問,誤謬などがあれば,

それぞれの記事にコメントしてもらえると幸いです.



また,今回の一連の文章は

リンクフリーです.

また,出典を明確にして頂ければ,

内容の転載も可能です.

その際は,コメント欄を利用して一言お願いします.



この"MATLAB Programming Style Guideline"の英語の原本は

以下のリンクからダウンロードできます.

・MATLAB Programming Style Guidelines - File Exchange - MATLAB Central

・Datatool社のHP

・PDFファイルへの直リンク



また,Richard Johnson氏は,

より詳細なMATLAB Programming Style Guidelineを広めるために,

以下の本を出版しています.

The Elements of MATLAB Style
The Elements of MATLAB Style

もし,より深くMATLABのプログラミング作法を学びたい方は,

こちらも参考にすると良いと思います.



最後に,

今回の翻訳は,Richard Johnson氏に直接許可を頂いています.

Richard Johnson氏の寛大な心と素晴らしい仕事に,

深く感謝します.


Statements

変数と定数

ルール1:メモリの問題が無い限り,変数の再利用はしない.

すべての変数はユニークで,

その部分だけで使用されることを約束すれば,

コードの可読性は向上します.



その変数の定義を誤解するような変数の使い方は控えるべきです.


ルール2: 関連のある同型の変数は,同一のコードで一緒に宣言する.

同様に,関連の無い変数は,

同一のコードで一緒に宣言すべきではありません.

これによって,変数のグループを理解しやすくなります.

persistent  x, y, z
global  REVENUE_JANUARY, REVENUE_FEBRUARY

ルール3: 重要な変数はファイルの初めにコメントとして説明する

他の言語において,

その変数が宣言された時に,

その変数の説明をすることは一般的です.

しかし,MATLABでは変数の宣言は基本的にしないので,

コメントとして,その変数の説明を書きます.

ex)

 % pointArray Points are in rows with coordinates in columns.

ルール4: 定数の説明は,定数の定義の後ろにコメントとして書く.

このルールによって,

この定数の値の決定理由や,

使用方法,制限条件などを記述することができます.

ex)

THRESHOLD = 10;  % Maximum noise level found by experiment.

グローバル変数

ルール1:グローバル変数の使用は最小限にしましょう.

関数の可読性とメンテナンス性のために,

関数に値を渡す時は,

グローバル変数ではなく,引数で渡すようにしましょう.

グローバル変数を使わなくてはいけない状況において,

その内の幾つかは "persistent"*1や, "getappdata"*2コマンドで

使用しなくてもよくなることが多い.


ルール2:グローバル定数は最小限にしましょう.

グローバル定数は使用せずに,

mファイルやmatファイルを使用して,

変数を宣言しましょう.



これによって,

どこで定数が定義されるのかが明確になります.

同様に,意図しない再定義も防ぐことができます.

もし,そのファイルにアクセスされることを望まないなら,

グローバル定数の構造体を利用することを考えましょう.


ループ

ルール1:ループ変数はループの直前で初期化する.

これによってループの速度が向上し,

もしループがすべてのインデックスの分だけ

回っていなかった時に

変な値になることをを防ぐことができます.


result = zeros(nEntries,1);
for index = 1:nEntries
	result(index) = foo(index);
end

ルール2:breakやcontinueはループの中で使用するのは最低限にしましょう.

このルールは,goto文に関するものと同じです.

breakやcontinue文はコードがそれによって

より可読性を向上させるものでない限り,

使用しないほうがいいでしょう.


ルール3: ネストしたループの最後にはコメントを入れましょう.

ネストした長いループの最後にコメントを入れることは,

コードの可読性を向上させますし,

そこまでのコードでどのような行為が行われたのかを

伝えることができます.


条件文

ルール1:複雑な条件文を使用することは控えるべきです.

もし,複雑な条件文を使用しなければならない時には,

以下の例のように,一時的な論理変数を利用すべきでしょう.

論理変数を利用することにより,

プログラム自体が自身のドキュメントになります.

そして,よりコードを読みやすくし,

デバックしやすくするでしょう.


if (value>=lowerLimit)&(value<=upperLimit)&~ismember(value,valueArray)
	: 
end

以上のプログラムは,以下のように書き直すべきです.

isValid = (value >= lowerLimit) & (value <= upperLimit);
isNew   = ~ismember(value, valueArray);
if (isValid & isNew)
       :
end

ルール2:基本的にif文を使う時には例外処理としてelse文も一緒に使用する.

このルールによって,

コードの可読性が向上し,

そのif文の例外の部分がどのようになるかを

わかりやすくします.

fid = fopen(fileName);
if (fid~=-1)
	: 
else
	: 
end

ルール3:条件文で"if 0"は使用すべきではありません.

"if 0"を使うことによって,

その部分をコメントのように

利用しないようにすることができます.

しかしこれは,

コードが実際にどのような振る舞いをするのかを

不明瞭にするので,使用しないほうがいいでしょう.

ブロックコメントにしたいのなら,

エディタの機能を使って,ブロックコメント化するべきです.


ルール4:switch文にはotherwise文を必ず付けましょう.

switch文で,otherwise文を付け忘れるのは,

よくあるミスです.

これは,コードが不可解な振る舞いをする

可能性があるので,止めましょう.

switch (condition)
case ABC
	statements;
case DEF
	statements;
otherwise
	statements;
end

ルール5: switch文の条件変数はstring文にしましょう.

文字列変数は,それ自体が意味を持つので,

数字の変数を使用するよりも,

コードの意図を伝えやすくなります.


一般的なこと

ルール1:曖昧なコードを書くのは止めましょう.

これはプログラマは陥りがちなことですが,

このシェイクスピアの言葉に感化される人は非常に多いです.

"短いことこそ,ジョークの真髄だ."

MATLABを書く時にも使えると考えるのも

しょうがないことなのかもしれません.

簡潔なコードを書くことは,

様々な言語の特徴を知る上で,

有効な方法だと言えるでしょう.

しかし,一般的に,

コードの最終的なゴールは,

言語の特徴を学ぶことではなく,

コードの明確性を向上させることです.


Math WorksのSteve Lordはこのように言っています.

"今から,一ヶ月後,

自分がそのコードを見たら,

何をするコードなのかを理解することができるか?

それを常に心に止めておくことが重要なのです.”



他にも,コードの簡潔性のみを追い求めることの問題を

多くの人が指摘しています.

Martin Fowlerは言いました.

"どんな馬鹿でも

コンピュータが理解できるコードは書くことができる.

けど,良いプログラマというのは,

人間が理解できるコードを書くことができるんだ"



KreitzbergとShneidermanもこう言っています.

"プログラミングは楽しいものです.

そして,わかりにくくすることもできます.

しかし,それらは決して両立しません."


ルール2:括弧を使いましょう.

MATLABには,演算子の優先権に関するルールが文書化されています.

しかし,だれがそのようなルールの詳細まで覚えているでしょう.

もし,誰もがわかりやすいコードを書くのであれば,

それぞれの式をわかりやすくするために括弧を利用すべきです.

これによって,論理式を拡張したい場合に,

非常にコードが読みやすくなります.


ルール3:数式の中では,数字をそのまま使用するのは最小限にしましょう.

数式の中で数字を使いたい時には,

代わりに名前のついた定数に数字を代入して,

その定数を数式に利用するようにしましょう.



なぜなら,もし数字が明確な意味を持たなかったなら,

そのコードの可読性は著しく損なわれるでしょう.

代わりに名前のついた定数を利用することにより,

可読性は著しく向上します.


また,このルールを徹底することにより,

その数字の値を変更したい時に,

ファイル内のその数字の値をすべて変更するよりも,

たった一つの定数宣言の値のみを変更すればよいので,

よりコードの改変が楽になります.


ルール4 浮動小数点数の定数は,必ず少数点の前の数字も書きましょう.

これは数学の構文のルールとして決められているものです.

また,0.5という数字は.5と表記するより,

読みやすいのは確かです.

これでは整数の5と見間違えてもしょうがないといえます.

ex)

◯ THRESHOLD = 0.5;
× THRESHOLD = .5;

ルール5 浮動小数点数の比較は細心の注意を払う.

二値の表現は問題を引き起こしがちです.



次の例を見てみましょう.

shortSide = 3;
longSide = 5;
otherSide = 4;
longSide^2 == (shortSide^2 + otherSide^2)
ans =
          1

これは想像通りです.

では次はどうでしょうか?

scaleFactor = 0.01;
(scaleFactor*longSide)^2 == ((scaleFactor*shortSide)^2 +(scaleFactor*otherSide)^2)
ans = 0

なぜこうなるのでしょうか?

MyEnigma Supporters

もしこの記事が参考になり、

ブログをサポートしたいと思われた方は、

こちらからよろしくお願いします。

myenigma.hatenablog.com

*1:MATLAB関数内のみで内部的に変数値を保持させることができるキーワード.つまり,C言語におけるstaticと同じような振る舞いを変数に可能にさせることができ,再帰関数などでグローバル変数を使用しなくてもよくなる.

*2:GUIなどから変数値を取得できるコマンド