Slide 1

Slide 1 text

【第4回】ゼロから始めるゲノム解析 (Python編) Creating the Fibonacci Sequence: Writing, Testing, and Benchmarking Algorithms @onouyek

Slide 2

Slide 2 text

本勉強会の概要・目的 書籍名 対象者/目的 Mastering Python for Bioinformatics Python・バイオインフォ知識ほぼゼロの人 を対象に、正しいPythonのコーディング手 法について学ぶ 頻度 毎週〜隔週開催予定 登壇者 募集中!

Slide 3

Slide 3 text

Rosalindとは ● 問題解決を通じてバイオインフォマティク ス、プログラミング、およびアルゴリズムを 学習するためのプラットフォーム ● 大学やハッカソン、就職の面接にも 600回 以上の採用実績あり 参考:https://qiita.com/_kimoton/items/d534d0fa9b83dd7dc412 概要

Slide 4

Slide 4 text

環境構築 - 必要パッケージ群のインストール # 公開されているレポジトリからファイル群を取得 $ git clone https://github.com/kyclark/biofx_python $ cd biofx_python # requirements.txt に記載のパッケージをインストール $ pip3 install -r requirements.txt # pylintの設定ファイルをホームディレクトリに移動 $ cp pylintrc ~/.pylintrc # mypyの設定ファイルをホームディレクトリに移動 $ cp mypy.ini ~/.mypy.ini

Slide 5

Slide 5 text

本日のお題 http://rosalind.info/problems/fib/ 正の整数n(<=40)、k(<=5)が与えられる。1ペアから始めて、各世代において繁殖年齢のペアのウサギが kペ アのウサギの子孫を残すとしたとき、 nか月後に存在するウサギのペアの総数を求めよ。

Slide 6

Slide 6 text

本日学ぶこと ● 引数の評価とエラーの出し方 ● listのスタックとしての使い方 ● ジェネレーター関数の書き方 ● 再帰関数の書き方 ● メモ化を用いた高速化 ● デコレーターの使い方

Slide 7

Slide 7 text

argparseの型チェック argparseのtypeにintを指定しておけば異なる型で入力されるとエラーになる $ ./fib.py 5 3.2 usage: fib.py [-h] generations litter fib.py: error: argument litter: invalid int value: '3.2' $ ./fib.py -3 2 usage: fib.py [-h] generations litter fib.py: error: generations "-3" must be between 1 and 40 今回の問題の条件である 1<=n<=40、1<=k<=5を満たさない 場合にエラーを上げたい場合はどう すればよいか?

Slide 8

Slide 8 text

引数のバリデーション ①args.genはint型なので条件比較する ことができる ②条件に合わない場合は parse.error() でエラーを上げてプログラムを終了でき る ① ②

Slide 9

Slide 9 text

Solution 1: listをスタックとして用いる ①n=0、n=1のときのペア数0,1をスタックにいれておく ②n=2以降の計算結果(F n = F n-2 *litter + F n-1 )をスタックに追加 ③スタックに最後に入れた数が nヶ月後に存在するペア数 ① ② ③ スタック:LIFO (Last-In-First-Out) 1 3 2 1 3 2 Push Pop

Slide 10

Slide 10 text

Solution 2: ジェネレーター関数を使う ① ② ③ yieldを使うと関数の呼 び出しごとに結果が返 されるジェネレーターに なる ①x,yを0,1で初期化 ②1世代前の値を返す ③2世代前のxを1世代 前yのk倍に置き換え、1 世代前yを直近2世代の 和に置き換える x=0 y=1 yield x 0 0 x=0 y=1 yield y x=y*k=2 y=x+y=1 1 1 x=2 y=1 yield y x=y*k=2 y=x+y=3 1 2 x=2 y=3 yield y x=y*k=6 y=x+y=5 3 3 x=6 y=5 yield y x=y*k=10 y=x+y=11 5 4 x=10 y=11 yield y x=y*k=22 y=x+y=21 11 5 k=2の例

Slide 11

Slide 11 text

(参考)itertools.islice() for文の代わりにislice()を使えば、指定した 要素まで返すイテレーターが作られる islice(イテラブル, 要素数) リストにして最後の要素を取得

Slide 12

Slide 12 text

Solution 3-1: 再帰関数を使う ①終了条件:nが1または2になったら1を返す ②それ以外は2世代前と1世代前のfib()が呼ばれる 下図のようなスタックコールが作られていき計算される ① ② fib(5) fib(3) fib(4) fib(2) fib(3) fib(1) fib(2) fib(1) fib(2)

Slide 13

Slide 13 text

Solution 3-2: メモ化による高速化 ① ② 毎回計算するのは効率が悪い ①空の辞書を作る ②辞書にない場合だけ計算する fib(5) fib(3) fib(4) fib(2) fib(3) fib(1) fib(2) fib(1) fib(2)

Slide 14

Slide 14 text

Solution 3-3: メモ化(デコレーター) fib関数の上に@memoizeとすることでメモ化機 能を上書くことができる

Slide 15

Slide 15 text

Solution 3-4: functools.lru_cache() memoize関数を作らなくてもfunctoolsライブラリにlru_cache関数が使える

Slide 16

Slide 16 text

ベンチマークツール:hyperfine ①複数回実行した平均値がわかる ②サマリーで速度比較の結果がわかる demo ① ② https://github.com/sharkdp/hyperfine

Slide 17

Slide 17 text

randomを使ってランダム値でテストする ①random.choice()で与えられたシーケンスか らランダムに要素を返す ②random.randint(a, b)でa<=N<=bからラン ダムな整数を返す ① ② ① ②

Slide 18

Slide 18 text

makeコマンドからテストを実行する Makefileにテストコマンドを記述しておけばmake testでテストが実行できる

Slide 19

Slide 19 text

すべてのSolutionをまとめてテストする ①re.match()で正規表現にマッチする ファイルを取得 ②取得したファイルに対してテストを実行 ① ②

Slide 20

Slide 20 text

本日学んだこと ● 引数のバリデーションとparser.error()によるエラーの上げ方 ● listのスタックとしての使い方 ● yieldを使ったジェネレーターの作成 ● 再帰関数の書き方とメモ化による高速化 ● デコレーターの使い方 ● hyperfineによるベンチマーキング ● randomモジュールによる値のランダム生成