Share
Embed
【第1回】ゼロから始めるゲノム解析(Python編).pdf
2021/11/05 (金) 【第1回】ゼロから始めるゲノム解析(Python編) 資料
nkimoto
November 05, 2021
Transcript
37 slides
-
環境構築 - 必要パッケージ群のインストール # 公開されているレポジトリからファイル群を取得 $ 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 demo -
本日学ぶこと • argparseを用いたコマンドライン引数の利用、型チェック • テスト駆動開発(TDD)について • pytestを用いたテストの書き方 • 文字列のイテレーションの仕方 •
文字列に含まれる要素のカウント方法 • if/elifを用いた決定木の作り方 • 文字列への変数代入の方法 -
linterを使ったコードの静的解析 demo 特徴 出力例 • pep8のチェック、pyflakesのチェック、 及び循環的複雑度をチェックできる • オプションやプラグインが豊富でカスタ マイズの幅が広い
• githubスター数 1.6k • $ flake8 [ファイル名] で実行 flake8 • 老舗のツール。effective pythonで推奨 されている • VSCodeのデフォルトのlinter • githubスター数 3.6k • $ pylint [ファイル名] で実行 pylint sample.py:1:1: F401 'time' imported but unused sample.py:5:1: E302 expected 2 blank lines, found 1 sample.py:5:15: E231 missing whitespace after ',' sample.py:7:5: F841 local variable 'varC' is assigned to but never used C: 5, 0: Exactly one space required after comma def func1(varA,varB): ^ (bad-whitespace) C: 8, 0: Unnecessary parens after 'return' keyword C: 1, 0: Missing module docstring 殆どのエディターで対応する構文チェッカーが存在 (vimの場合、syntastic等) -
argparseとは Pythonの実行時にコマンドライン引数を取りたい場合に使用する $ python dna.py --help usage: dna.py [-h] DNA
Tetranucleotide frequency positional arguments: DNA Input DNA sequence optional arguments: -h, --help show this help message and exit dna.pyでは、 位置引数として DNA オプション引数として --help が定義されている -
argparseの定義の仕方 1 get_args()関数の中で引数解析 2 引数として受け取りたい変数名及び ヘルプメッセージにおける記載を定義 1 2 3 3
parse_args()メソッドで引数を解析 4 4 コマンドライン引数で受け取った値が 属性値で使用できるようになる -
Named Tuple >>> from typing import NamedTuple >>> class Sequence(NamedTuple):
... id: str ... seq: str ... NamedTupleの作成 >>> type(Sequence) <class 'type'> NamedTupleはtype型のオブジェクト 参考:https://docs.python.org/ja/3/library/collections.html#collections.namedtuple NamedTupleを使うと その構造が持つ属性の型を定義することがで きる → 静的型チェッカーによる異常検出が可能 -
Named Tuple の特徴 >>> seq1 = Sequence('CAM_0231669729', 'GTGTTTATTCAATGCTAG') >>> seq2
= Sequence(seq='GTGTTTATTCAATGCTAG', id='CAM_0231669729') 位置変数またはkey/valueで引数を渡してSequence型のオブジェクトを作成 >>> 'ID = ' + seq1[0] 'ID = CAM_0231669729' >>> 'seq = ' + seq1[1] 'seq = GTGTTTATTCAATGCTAG' >>> 'ID = ' + seq1.id 'ID = CAM_0231669729' >>> 'seq = ' + seq1.seq 'seq = GTGTTTATTCAATGCTAG' インデックスでも属性名でも取り出せる -
Named Tupleとargparseを用いたプログラム構成 1 1 get_args()関数の中で引数解析 2 2 Argsクラス(NamedTuple)に変換 3 Argsクラスはstr属性のdnaを持つと定義
しているため、数値演算を行う構文がある とmypy等の静的型チェッカーでエラーが 出る 3 4 慣習的に、プログラムを直接実行された場 合、main()関数を実行する構成とする 4 -
テスト駆動開発(TDD) 1. 仕様に沿ってテストを作成 2. 全てのテストを実行し、新規のテストが落ちて いることを確認 3. テストがクリアするようにコードを書く 4. 必要に応じてリファクタリング
5. 1~5を繰り返す! TDDの流れ TDDでは、開発者がコードを書く前に要件に集中できる -
(参考)文字列のイテレーション >>> dna = 'ACGT' >>> for base in dna:
... print(base) ... A C G T 文字列のイテレーション例 1 2 1 2 dna文字列の各文字はbase変数にコピー される print()関数は改行を追加するため、各 塩基は別の行として出力される -
解法 2 count() 関数の作成 & 単体テストの追加 1 2 1 2
型ヒントで、count()関数は文字列を入 力値として受け、4つの整数値が入ったタ プルを返すことを定義 カウント部分はmain()関数からcount() 関数に異動 関数化のメリット: • main()関数の可読性が高くなる • 関数ごとに機能のテスト(単体テスト)が 書ける -
(参考)単体テストの書き方 1 2 1 2 pytestを使う場合、テスト関数名は test_から始める必要がある。 空文字列が与えられた時に全て 0のタプル を返すこと、各文字列が与えられた際に想
定したタプルを返すことを確認 $ pytest -v dna.py ============================ test session starts ============================= … collected 1 item dna.py::test_count PASSED [100%] ============================= 1 passed in 0.01s ============================== テストの実行 -
解法 3 str.count()メソッドの利用 1 2 1 2 count()関数は文字列を入力値として 受け、4つの整数値が入ったタプルを 返すことを定義
文字列型の.count()メソッドを呼び 出してカウント -
(参考)f文字列による変数代入 >>> seq = 'ACGT' >>> f'The sequence "{seq}" has
{len(seq)} bases.' 'The sequence "ACGT" has 4 bases.' f文字列の使い方例 1 2 1 2 4つのカウント値を count_変数に格 納 f文字列を使った変数代入 format()メソッドと比較して 可読性が高いため、基本的に はf文字列を利用すべき -
解法 4 辞書型を利用(全てカウント) 1 2 count()関数は文字列を入力値として 受け、4つの整数値が入ったタプルを 返すことを定義 counts辞書を空辞書として初期化 3
dnaに含まれる文字列を1文字ずつ見 ていき、counts辞書の要素として存 在しなければ0として初期化。既に存 在していればカウントアップ 1 2 3 4 4 dict.get()メソッドを使うことで、 default値として0を使うことができ る -
解法 5 辞書型を利用(カウント対象のみカウント) 1 2 1 2 count()関数は文字列を入力値として 受け、Keyが文字列、Valueが整数型 の辞書を返す関数として定義
counts辞書を4つの塩基について カウント数0で初期化 3 3 dnaに含まれる文字列を1文字ずつ見 ていき、counts辞書の要素があれば カウントアップ -
(参考)collections.defaultdictクラス >>> from collections import defaultdict >>> counts = defaultdict(int)
>>> counts['A'] 0 >>> counts['C'] += 1 >>> counts defaultdict(<class 'int'>, {'A': 0, 'C': 1}) defaultdictクラスの使い方例 参考:https://docs.python.org/ja/3.6/library/collections.html#collections.defaultdict -
追加課題 - TDDに沿ったコーディングの流れ 1. 大文字と小文字が混在する入力ファイルを用意 2. test/dna_test.pyに用意したファイルを入力として新規のテストを作成 3. 全てのテストを実行し、新規のテストが落ちていることを確認 4.
プログラムを修正 5. テストを走らせる 6. テストが走るようにリファクタリング 7. 1~6を繰り返す! demo