Pythonで綺麗なコードを書く

みんなのPython勉強会#91
辻真吾(@tsjshg)

お前誰よ?(自己紹介)

  • 大学の研究所に勤めています

    • エネルギーシステムとバイオインフォマティクス
    • 応用データサイエンスという分野を作りたい
  • Stapyスタッフ

    • いつもありがとうございます
  • www.tsjshg.info

あらすじ

  • 最近でた本のはなし

    • 『応用基礎としてのデータサイエンス(講談社)』
  • Pythonで綺麗なコードを書く

    • PEP8
    • Pythonプログラミングの落とし穴
    • などなど

2/14に発売されました

詳細はこちら

応用基礎としてのデータサイエンス

  • 講談社データサイエンス入門シリーズの1冊
  • 『教養としてのデータサイエンス』の続編
  • データサイエンスに関する話題はほぼ網羅
  • 一般論に加えて専門的な話題も含む
    • でも数式は少なめ
    • 数学基礎を解説した節はある
  • この分野を俯瞰するのに良い本
  • 演習問題付きなので理解の確認ができる

担当したのは

  • コンピュータの基礎からアルゴリズムまでを扱った3.2節
  • 『Pythonで学ぶアルゴリズムとデータ構造』の超縮約版
    • +プログラミングの基礎
  • イースターエッグを仕込んでありますので気付いた方はご一報ください
    • (注)景品はありません

ここからは

Pythonで綺麗なコードを書く話

まずはここから

PEP8(ぺっぷえいと)をご存じですか?

PEPとは?

  • Python Enhancement Proposalsの略
  • Pythonを良くするための提案
  • 若い番号は特別な意味がある
    • PEP0: インデックス
    • PEP1: PEP自体の説明
    • PEP7: Cのスタイルガイド
    • PEP8: Pythonのスタイルガイド
  • PEP572
    • 代入式(セイウチ演算子)の提案
    • 2018年7月GuidoさんのBDFL引退のきっかけを作ったと言われている

PEP8に従おう!

日本語あります

まずは簡単なところから

カンマのあとにはスペース1つ


my_list = [1, 2, 3]
my_matrix = [[1, 2], [3, 4]]

余計な空白は入れない

my_list = [ 1, 2, 3 ]
# これが正解
my_dict = {1: "a", 2: "b", 3: "c"}
# これはよくない
my_dict = {1:"a", 2 : "b", 3: "c" }

Pythonと言えばインデント

インデントはスペース4つ

for i in range(5):
    if i % 2 == 0:
        print("偶数キタ")

入力するときはタブキーを使ってもよいですが、テキストエディタの設定で保存するときスペースに変換されるようにしておくと良い

1行で書いてもいい(あまり推奨されない)

for i in range(10):
    # 3回で飽きたのでループを抜ける
    if i == 2: break

elseがあるときは(動くけど)ダメ

for i in range(10):
    if i % 2 == 0: print("偶数キタ")
    else: print("なんすかこれ?")

変数名

  • 小文字とアンダースコア
    • 関数やメソッドの名前
    • インスタンスに紐付く変数
  • 単語の先頭を大文字で連結
    • クラスの名前
    • pow
    • pandas.DataFrame.set_index

いろいろあって、覚えられん!

ツールを使う

  • Linter

    • コードのチェックして問題点を注意してくれる
    • pylintなど
  • Code Fotmatter

    • コードをスタイルガイドに合うように修正してくれる
    • blackなど

大前提

過去の自分は赤の他人

自分で書いたコードですらわからなくなるのに、いわんや他人のコードをや

ガイドラインに従ったコードを書く重要性

import this

ってやったことあります?

Pythonの哲学が19行出てきます

お気に入りはこれ

There should be one, and preferably only one, obvious way to do it.

なにかするとき、できるならそれを実現するただ1つの書き方があるとよい。

こんなのもあります

Although that way may not be obvious at first unless you’re Dutch.

そうは言っても、オランダ人じゃねーとわからんかもしれんが。

Pythonでコードを書くとき

よく言われる注意事項

組み込み関数を上書きしない

絶対ダメ!

# ×
list = [1, 2, 3]
# 〇
my_list = [1, 2, 3]

変数名を考えるのは大変

でも安直にlistはだめ

組み込み関数listが以後使えなくなってしまう

多くの環境でキーワードは色が変わるので参考になる

誰も知らない組み込み変数

creditscopyrightという変数にデータが紐付いている

こちらは上書きしてもそれほど影響ない

credits

Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information.

Pythonの変数は箱じゃない

このコードの実行結果は?

a_list = [1, 2, 3]
b_list = a_list
b_list[0] = 4
print(a_list)
  1. [1, 2, 3]
  2. [4, 2, 3]
  3. [0, 2, 3]
  4. [4, 1, 2, 3]

Pythonの変数は箱じゃない

正解は

a_list = [1, 2, 3]
b_list = a_list
b_list[0] = 4
print(a_list)

[4, 2, 3]

変数への代入は実体をコピーしない

Pythonの変数は箱じゃない

コピーしたいのならcopyメソッドを使う

a_list = [1, 2, 3]
b_list = a_list.copy()
b_list[0] = 4
print(a_list)

[1, 2, 3]

このあたりの動作はプログラミング言語ごとに違う

初心者から有能なプログラマーへの道のりは険しく、身につけなければならない知識量は、まるで消火ホースから流れ出る水のように大量で、飲み込むのも苦しいと感じるかもしれません。

『きれいなPythonプログラミングAl Sweigart(著) 岡田祐一(訳)』はじめにviiページより

どうしてこうなるかわかります?

a_to_Z = ['z', 'Z', 'a', 'A']
sorted(a_to_Z)

[‘A’, ‘Z’, ‘a’, ‘z’]

Python3の内部では文字をUnicode(UTF-8)で処理している。Unicodeでは半角英数字などの文字コードがASCIIと互換性を保つようにつくられている。ASCIIでは英大文字は英小文字より若い文字コードとしてならべられており、Pythonで文字列をソートする場合はこの文字コードという数値をもとに順番を決めるためこの結果になる。

returnは1つ?

よくあるFizzBuzz問題

引数が3で割り切れたらFizz、5で割り切れたらBuzz、両方で割り切れたらFizzBuzz、それ以外なら数字を文字列にして返す

def fizz_buzz(num):
    res = ""
    if num % 3 == 0:
        res += "Fizz"
    if num % 5 == 0:
        res += "Buzz"
    if res == "":
        res = str(num)
    return res

returnは1つ?

これでもいい

def fizz_buzz(num):
    res = ""
    if num % 3 == 0:
        res += "Fizz"
    if num % 5 == 0:
        res += "Buzz"
    if res == "":
        return str(num)
    return res

returnは1つ?

それなら、こうか?

def fizz_buzz(num):
    res = ""
    if num % 3 == 0:
        res += "Fizz"
    if num % 5 == 0:
        res += "Buzz"
    return res if res else str(num)

GitとGitHubの章や、アルゴリズムと$\mathcal{O}$(オーダー)記法の基礎的な説明もある

WebアプリケーションフレームワークDjangoの話題を含め、現場ですぐに役立ちそうなコーディングのノウハウが満載

まとめ

  • 『応用基礎としてのデータサイエンス』でました
  • PEP8に従いましょう
    • 過去の自分は赤の他人
  • 有能なプログラマーへの道のりは険しい
    • 何事も地道な努力の継続