- 児島 孝典
- (株) 144Lab
- ソフトウェア開発のお仕事
- Go, Python
- Twitter: max747
- バリバリ業務で使っている
- ちょくちょく普段使いを始めた
- 文法はひととおりおさえた
Python 標準ライブラリを使って小さなツールを作ってみましょう。
- 文法まわりのおさらい (30分)
- ツールを作ってみる (60分)
特定分野に特化した話
- Web アプリケーション
- 機械学習
- データサイエンス
- etc
- たくさん読んで書く(量)
- より良いコードを書こうとする意志(質)
- 読みやすい
- 動的型付け言語
- 型に対して厳格
- 豊富な標準ライブラリ
- battery included
- Python 3
- Python 2 のサポートは 2020 年まで
- 過去資産のメンテナンス
- できるだけ早く Python 3 にしましょう
- いま使いたいライブラリが Python 3 未対応
- できれば Python 3 対応しているライブラリを探しましょう
- 過去資産のメンテナンス
- 数値 (整数、浮動小数点数)
- ブール値
- 文字列
- バイト列
- リスト
- タプル
- 辞書
- None
- if
- for, while
- try, except, finally
- 内包表記
def fn1():
"""
何もしない関数。
"""
# do something ...
pass
def fn2(arg1, arg2):
return 0, 1
def fn3(*args, **kwargs):
print(args)
print(kwargs)
class Foo:
class_attr = "attribute of Foo"
def __init__(self):
self.instance_attr = "instance attr"
def fn(self):
return "method of Foo"
Bad pattern:
class Bar:
box = []
def add(self, item):
self.box.append(item)
val = 0
def fn():
val = 1
print(" a:", val)
def inner():
val = 2
print(" b:", val)
print("c1:", val)
inner()
print("c2:", val)
fn()
print(" d:", val)
- 名前の前後にアンダースコアが 2 つついている
- 最初は気にしなくて良い
- 気になり出したら、それは Python に慣れてきたということ
def main():
# do something...
pass
if __name__ == "__main__":
main()
__name__
属性- 直接実行された場合は
__main__
- モジュールとしてインポートされた場合は、モジュール名
- 直接実行された場合は
def proc_a(*args, **kwargs):
print("proc_a called")
print(args)
print(kwargs)
def proc_b(*args, **kwargs):
print("proc_b called")
print(args)
print(kwargs)
class Dispatcher:
def __init__(self):
self.table = {}
def register(self, name, fn):
self.table[name] = fn
def dispatch(self, name, *args, **kwargs):
fn = self.table[name]
return fn(*args, **kwargs)
dp = Dispatcher()
dp.register('a', proc_a)
dp.register('b', proc_b)
if __name__ == "__main__":
dp.dispatch('a', 1, arg='hello')
dp.dispatch('b', 2)
import foo
from bar import baz
import hoge.fuga
import piyo as p
- 郵便番号データをダウンロードし、所定の位置に配置する。
- 使用する郵便番号データは http://zipcloud.ibsnet.co.jp/ にあるもの。
- ダウンロードした zip は展開して中身を取り出す。
- 取り出した csv ファイルの内容を JSON に変換する。
- JSON には以下の内容が含まれていること。
- 郵便番号
- 住所(よみ)
- 住所
- また、JSON ファイルのエンコーディングは UTF-8 であること。
- csv の仕様は http://www.post.japanpost.jp/zipcode/dl/readme.html を参照。
- Python インタプリタを活用しましょう。
- モジュールの使い方を確認する。
- 小さな手続きを実際に実行してみる。
dir()
やhelp()
が便利です。
まずは csv を JSON に変換する手続きを実装しましょう。
csv ファイルを読み込むプログラムを書きましょう。
ヒント:
- open 関数 と csv モジュールを使用します。
- ファイルの文字コードに注意しましょう。
- 郵便番号データファイルには、文字コード cp932 が使われています。
- 郵便番号データは、試行錯誤の段階で取り扱うには大きすぎます。 先頭 50 行など、適当な範囲を切り出して利用しましょう。
読み込んだ csv ファイルから JSON データを作り、出力しましょう。
ヒント:
- json モジュールを使用します。
- JSON にする予定の値を辞書に保存しておくと、後に JSON にするときに便利です。
- JSON を整形して出力する
続いて、ファイルをダウンロードする手続きを実装しましょう。
指定の URL にアクセスし、郵便番号データをダウンロードして保存するプログラムを書きましょう。
ヒント: urllib.request モジュールの urlopen 関数を使用します。
zip ファイルを展開するプログラムを書きましょう。
ヒント: zipfile.ZipFile を使用します。
記述したプログラムに仕様変更が発生しました。対応してください。
- プログラム実行時点の日付でディレクトリを作り、そこに zip を保存する。
- 日付を得るには datetime モジュールを使用します。
- ディレクトリを作るには os モジュールを使用します。
- 最新のダウンロードデータは latest ディレクトリにも保存する。
- csv ファイルは latest ディレクトリにあるものを読み込む。
この変更の意図は、過去にダウンロードしたファイルの履歴を残すことです。
- 半角カナで書かれている住所(よみ)の情報を、全角に置き換える。
- 半角カナを全角カナに置き換えるには unicodedata モジュールを使用します。
この変更の意図は、JSON を受け取る側の読みやすさへの配慮です。
- github から ssh 公開鍵をダウンロードして保存する
- 時報を slack に投げる
- Web サーバーのアクセスログを加工する
- etc ...
- PyPI
- the Python Package Index
- https://pypi.python.org/
- pip
- simplejson
- requests
- python-dateutil
- virtualenv
- pytz
- Jinja2
- 誰でも最初は初心者
- とにかく読んで書く
- Python インタプリタを活用しよう
- 作りたいものがある人は、作ってみよう
- 作りたいものが見つからない人は、まずは身の回りの雑多な作業を Python にやらせてみよう