コードを綺麗に

研究で、機械学習をやり始めて早半年、綺麗なコードを書けるようになっときたいなぁということで調べました。

#~~キャメルケース~~
これは複合語をひと綴りとして、要素語の最初を大文字で書き表す記法である。


|                      名称                      |     表記例     |                 備考                 |
|:----------------------------------------------:|:--------------:|:------------------------------------:|
|  アッパーキャメルケース| GetInputReader | 先頭を大文字で |
| ローワーキャメルケース| getInputReader | 先頭を小文字で |

#~~システムハンガリアン記法~~
pythonでは型宣言がないため、長いコードを書く場合、変数がどんな型だったか迷うケースがあります。この記法を使用することでミスを減らすことができる。
ただ、

|      文字     |                意味                |     使用例     |
|:-------------:|:----------------------------------:|:--------------:|
|   b または f  |               論理型               |   bDirtyFlag   |
|       ch      |               文字型               |   chSeparator  |
|       by      |  バイト型   (符号なし1バイト整数)  |   byGrayLevel  |
|   n または i  |        整数型 (int, integer)       |     nPower     |
|       l       |           長整数   (long)          |      lDate     |
|       u       |            符号なし整数            |     uiCount    |
|       w       |           ワード型 (WORD)          |  wLanguageCode |
|       dw      |      ダブルワード型   (DWORD)      |     dwSize     |
|  fp または f  |         単精度浮動小数点型         |     fpPrice    |
|  db または d  |         倍精度浮動小数点型         |       dPi      |
|  p または lp  |             ポインタ型             |  lpDirectSound |
|       s       |              文字列型              |   sPlayerName  |
|       sz      |          ゼロ終端文字列型          |   szFileName   |
|       fn      |           関数ポインタ型           |   fnCallback   |
|       h       |             ハンドル型             |     hThread    |
| hwnd または h | ウィンドウハンドル型 (Windowsのみ) |   hMainWindow  |
|       g_      |           グローバル変数           |  g_iErrorCode  |
|       c_      |           定数   (const)           |  c_nBufferSize |
|       s_      |         静的変数   (static)        | s_pLookupTable |
|       m_      |        クラスのメンバー変数        |    m_nLength   |
|       C       |               クラス               |      CHoge     |
|      tag      |             構造体タグ             |     tagRECT    |


#命名規則
関数名、変数名はスネークケース、クラス名はキャメルケース、プライベートは"_"始まり。

|    対象    |                   ルール                  |          例          |             付録             |
|:----------:|:-----------------------------------------:|:--------------------:|:----------------------------:|
| パッケージ | 全小文字   なるべく短くアンダーバー非推奨 | tqdm, requests   ... |              　              |
| モジュール | 全小文字   なるべく短くアンダーバー非推奨 |      sys, os,...     |              　              |
|   クラス   |         最初大文字 + 大文字区切り         |    MyFavoriteClass   |              　              |
|    例外    |         最初大文字 + 大文字区切り         |  MyFuckingException  |              　              |
|   型変数   |         最初大文字 + 大文字区切り         |    MyFavoriteType    |              　              |
|  メソッド  |      全小文字 +   アンダーバー区切り      |  my_favorite_method  | 内部メソッドはアンダーで開始 |
|    関数    |      全小文字 +   アンダーバー区切り      |  my_favorite_funcion |              　              |
|    変数    |      全小文字 +   アンダーバー区切り      | my_favorite_instance |   内部変数はアンダーで開始   |
|    定数    |       全大文字 + アンダーバー区切り       |   MY_FAVORITE_CONST  |              　              |

#アンダースコア
**アンダースコア`_`**を使用したメソッドやメンバ変数には二種類存在する。

 - **シングルアンダースコア`_`**  ：  定義される関数は参照はできるが、基本的に外部から参照しないという**慣習規則**。
 - **ダブルアンダースコア`__`**  ：  プライベートっぽくする**文法規則**。

基本的には、プライベートなフィールドを記述する場合、**シングルアンダースコア`_`**で充分である。
**ダブルアンダースコア`__`**にすると一見外部から参照できないように見えるが、実際は`_ClassName__paramName`といった名前でアクセスができてしまう。これをネームマングリング(名前修飾)と言う。そもそもこの機能は、親クラスと子クラスで名前が衝突しないように作られた機能であって、プライベートなメンバ変数を提供するための機能ではないことに注意である。

```python:sampleclass.py
class SampleClass:
    def __init__(self):
        self.publicParam = 'publicParam'
        self._singlePrivateParam = '_singlePrivateParam'
        self.__doublePrivateParam = '__doublePrivateParam'
        
s = SampleClass()
print(s.publicParam)                      # publicParam
print(s._singlePrivateParam)              # _singlePrivateParam
#print(s.__doublePrivateParam)            # AttributeError: 'SampleClass' object has no attribute '__doublePrivateParam'
print(s._SampleClass__doublePrivateParam) # __doublePrivateParam
```
#docstring
Pythonでは関数やクラスなどの定義の直後に文字列を記述するとdocstringとして扱われる。
docstringは`print(関数名.__doc__)`や`help(関数名)`で出力できる。docstringの書き方は、`reST`,`Epytext`,`Google`,`Numpydoc`等があるが、広く使われているNumpydocでの記述例を以下に提示する。

##クラスコメント
```python:class
class Fruit(object):
    """
    果物の各属性値やヘルパー関数を保持する。

    Attributes
    ----------
    fruit_id : int
        対象の果物のマスタID。
    fruit_name : str
        果物名。
    price_dict : dict
        キーに地域のID、値に該当する地域での値段を保持した辞書。
    """
print(Fruit.__doc__)
#help(Fruit)

#果物の各属性値やヘルパー関数を保持する。
#
#Attributes
#----------
#fruit_id : int
##対象の果物のマスタID。
#fruit_name : str
##果物名。
#price_dict : dict
##キーに地域のID、値に該当する地域での値段を保持した辞書。
```

##メソッドコメント
```python:method
def get_fruit_price(fruit_id):
    """
    果物の値段を取得する。

    Parameters
    ----------
    fruit_id : int or None, default None
        対象の果物のマスタID。
    fruit_id_arr : array-like
        対象の果物のマスタIDを格納した配列。
    location_id : int
        対象地域のマスタID。

    Returns
    -------
    fruit_price : int
        対象の果物の値段。
    fruit_price_list : list of int
        果物の値段を格納したリスト。
    consumption_tax : int
        消費税値。

    See Also
    --------
    get_fruit_id_list : DBに保存されている果物のマスタIDのリストを取得する。

    Notes
    -----
    スイカは野菜側として扱われる。

    Raises
    ------
    ValueError
        Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity).

    Examples
    --------
    >>> a = np.array([[1,4],[3,1]])
    >>> np.sort(a)                # sort along the last axis
    array([[1, 4],
           [1, 3]])
    >>> np.sort(a, axis=None)     # sort the flattened array
    array([1, 1, 3, 4])
    >>> np.sort(a, axis=0)        # sort along the first axis
    array([[1, 1],
           [3, 4]])
    """
    # ...関数内容省略。
    return fruit_price
```

#mainブロック
mainとして実行されたときのみ処理が実行されるようにする方法である。
例えば、このsample.pyをimportなどした時はmainが実行されない利点がある。

```python:sample.py
if __name__ == "__main__":
    main()
```


#参考文献
>[Qiita 変数名の命名規則/＊＊ケースの使い分け](https://qiita.com/am_nimitz3/items/7b01af53751dba5d8fb1)
>[Wikipedia ハンガリアン記法](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%B3%E3%82%AC%E3%83%AA%E3%82%A2%E3%83%B3%E8%A8%98%E6%B3%95)
>[Qiita それっぽいPythonコードのテンプレート](https://qiita.com/estaro/items/55ae839d22bee1022150)
>[Qiita Python命名規則一覧](https://qiita.com/naomi7325/items/4eb1d2a40277361e898b)
>[Qiita 【備忘録】Pythonにおけるアンダースコア"_"の役割について](https://qiita.com/ikki8412/items/ab482690170a3eac8c76)
>[Qiita [Python]可読性を上げるための、docstringの書き方を学ぶ（NumPyスタイル）](https://qiita.com/simonritchie/items/49e0813508cad4876b5a)
>[コメントに関する規約](http://www.okapiproject.com/java/java_codeconventions/jcc_comment.htm)
>[sphinx入門 その2 コード内のdocstringの記述](https://www.python.ambitious-engineer.com/archives/935)
>[stackoverflow 標準的なPythonのdocstring形式は何ですか？](https://stackoverflow.com/questions/3898572/what-is-the-standard-python-docstring-format)
>[NumPy および Google スタイルの docstring をドキュメントに取り込む](http://www.sphinx-doc.org/ja/stable/ext/napoleon.html)
>[標準的なPythonのdocstring形式は何ですか？](https://code.i-harness.com/ja/q/3b7ccc)
>[[Pythonコーディング規約]PEP8を読み解く](https://qiita.com/simonritchie/items/bb06a7521ae6560738a7)