以下のように、DNAに基づいて個人を識別するプログラムを実装します。
$ python dna.py databases/large.csv sequences/5.txt
Lavender
始め方
ここでは、この問題をCS50 IDEにダウンロードする方法を説明します。CS50 IDEにログインし、ターミナルウィンドウで次の各コマンドを実行します。
- すでに存在している
pset6
ディレクトリに移動します。 wget https://cdn.cs50.net/2020/fall/psets/6/dna/dna.zip
を実行して、この問題のディストリビューションを含む (圧縮された) ZIPファイルをダウンロードします。unzip dna.zip
を実行して、そのファイルを解凍します。- そのZIPファイルを削除するには、
rm dna.zip
の後にyes
またはy
を実行します。 ls
を実行します。ZIPファイルの中にdna
というディレクトリがあるはずです。cd dna
を実行して、そのディレクトリに移動します。ls
を実行します。サンプルのdatabases
とsequences
のディレクトリが表示されます。
背景
生物の遺伝情報を担うDNAは、数十年にわたって刑事司法で利用されてきました。ですが、DNAプロファイリングは正確にはどのように機能するのでしょうか。DNAの塩基配列が与えられたとき、法医学者はどのようにしてそれが誰に属するかを同定できるのでしょうか。
DNAはヌクレオチドと呼ばれる分子の配列で、特定の形 (2重らせん) に配列しています。DNAの各ヌクレオチドは、アデニン (A) 、シトシン (C) 、グアニン (G) 、チミン (T) の4種類の塩基のうちの1つを含んでいます。ヒトのすべての細胞には数10億個のヌクレオチドが配列しています。この配列のいくつかの部分 (ゲノム) は、ほぼすべてのヒトで同一であるか、または少なくとも非常に類似していますが、配列の他の部分はより高い遺伝的多様性を有し、したがって集団全体ではより多様なものとなります。
DNAが高い遺伝的多様性を有する傾向がある1つの場所は、Short Tandem Repeats (STR) です。STRはDNA塩基の短い配列で、DNAの特定の位置で連続的に何度も繰り返される傾向があり、個々のSTR反復回数は個体によって大きく異なります。例えば、以下のDNAサンプルでは、AliceのDNAでSTR AGAT
が4回繰り返されており、Bobは同じSTRが5回繰り返されています。
1つではなく複数のSTRを使用することで、DNAプロファイリングの精度を向上させることができます。2人がひとつのSTRについて同じ数の繰返しをもつ確率が5%であり、解析者が10の異なるSTRに注目した場合、2つのDNA試料が偶然に一致する確率は約1000兆分の1です (すべてのSTRが互いに独立していると仮定すします) 。したがって、もし2つのDNAサンプルがそれぞれのSTRで繰り返し一致すれば、解析者はそれらが同一人物からのものであるとかなり確信することができます。FBIのDNAデータベースであるCODISは、DNAプロファイリングプロセスの一環として20種類のSTRを使用しています。
このようなDNAデータベースはどのようなものでしょうか。最も単純な形式では、DNAデータベースをCSVファイルとしてフォーマットすることが考えられます。CSVファイルでは、各行は個人に対応し、各列は特定のSTRに対応します。
name,AGAT,AATG,TATC
Alice,28,42,14
Bob,17,22,19
Charlie,36,18,25
上記のファイルのデータから、アリスはAGAT
という配列をDNAのどこかで28回連続して繰り返し、AATG
という配列を42回繰り返し、TATC
という配列を14回繰り返していることがわかります。一方、Bobは同じ3つのSTRをそれぞれ17回、22回、19回繰り返しています。チャーリーは同じ三つのSTRをそれぞれ36回、18回、25回繰り返しています。
DNAの塩基配列からそれが誰のものかどうやって特定するのでしょう?あなたがDNA配列を調べて、反復されるAGAT
の最も長い連続した配列を探し、最も長い配列が17回の長さであることを見つけたと想像してみてください。もしAATG
の最も長い配列が22回の繰り返しであり、TATC
の最も長い配列が19回の繰り返しであることがわかれば、DNAがボブのものであるというかなりよい証拠を提供することになります。もちろん、各STRのカウントを取得すると、DNAデータベース内の誰にも一致しなくなる可能性もあります。この場合、一致なしということになります。
実際には、解析者はどの染色体上のどの位置にSTRが見つかるかを知っているので、DNAのごく一部に検索を限定することができますが、この問題ではその詳細は無視しましょう。
あなたの課題は、DNAのシークエンスと個人のリストのSTR反復回数を含むCSVファイルを取るプログラムを書くことです。そして、DNAが (おそらく) 誰に属するかを出力します。
仕様
~/pset6/dna/
のdna.py
というファイルに、DNAのシークエンスが誰に属するかを識別するプログラムを実装します。
- プログラムの最初のコマンドライン引数として、個人のリストのSTR反復回数を含むCSVファイルの名前を必要とし、2番目のコマンドライン引数として、識別するDNA配列を含むテキストファイルの名前を必要とします。
- 誤った数のコマンドライン引数を指定してプログラムを実行すると、プログラムは選択したエラーメッセージを (
print
を使用して) 出力します。引数の数が正しい場合は、最初の引数が実際に有効なCSVファイルのファイル名であり、2番目の引数が有効なテキストファイルのファイル名であると仮定できます。
- 誤った数のコマンドライン引数を指定してプログラムを実行すると、プログラムは選択したエラーメッセージを (
- プログラムはCSVファイルを開き、その内容をメモリに読み込みます。
- CSVファイルの最初の行が列名であると仮定します。最初の列は単語名で、残りの列はSTRシーケンスそのものです。
- プログラムはDNA配列を開き、その内容をメモリに読み込む必要があります。
- 各STR (CSVファイルの最初の行から) について、プログラムは同定するためにDNA配列中のSTRの連続反復の最長の数を計算しなければなりません。
- STR反復回数がCSVファイル内の個人のいずれかと完全に一致する場合、プログラムは一致する個人の名前を出力する必要があります。
- STR反復回数は、複数の個人に一致しないと想定できます。
- 反復回数がCSVファイルのどの個人とも正確に一致しない場合、プログラムは
"No match"
を出力します。
ウォークスルー
使い方
プログラムは次の例のように動作します。
$ python dna.py databases/large.csv sequences/5.txt
Lavender
$ python dna.py
Usage: python dna.py data.csv sequence.txt
$ python dna.py data.csv
Usage: python dna.py data.csv sequence.txt
ヒント
- Pythonの
csv
モジュールは、CSVファイルをメモリに読み込むのに便利です。csv.reader
またはcsv.DictReader
のいずれかを利用できます。 open
関数とread
関数は、テキストファイルをメモリに読み込む場合に便利です。- プログラム内の情報を追跡するのに役立つデータ構造を検討します。
list
やdict
が役に立つかもしれません。 - Python文字列では「スライス」 (文字列内の特定の部分文字列へのアクセス) が可能です。
s
が文字列の場合、s[i:j]
は、文字i
から文字j
まで (文字j
自体は含みません) のs
の文字のみを含む新しい文字列を返します。 - DNA配列とSTRの両方を入力として、STRが反復する最大回数を返す関数を書くことから始めるとよいでしょう。この関数は、プログラムの他の部分でも使用できます。
テスト
この問題についてはcheck50
を使用できますが、次の各項目については、最初に自分でコードをテストすることをお勧めします。
- プログラムを
python dna.py databases/small.csv sequences/1.txt
として実行します。プログラムはBob
を出力するはずです。 - プログラムを
python dna.py databases/small.csv sequences/2.txt
として実行します。プログラムはNo match
と出力するはずです。 - プログラムを
python dna.py databases/small.csv sequences/3.txt
として実行します。プログラムはNo match
と出力するはずです。 - プログラムを
python dna.py databases/small.csv sequences/4.txt
として実行します。プログラムはAlice
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/5.txt
として実行します。プログラムはLavender
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/6.txt
として実行します。プログラムはLuna
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/7.txt
として実行します。プログラムはRon
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/8.txt
として実行します。プログラムはGinny
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/9.txt
として実行します。プログラムはDraco
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/10.txt
として実行します。プログラムはAlbus
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/11.txt
として実行します。プログラムはHermione
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/12.txt
として実行します。プログラムはLily
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/13.txt
として実行します。プログラムはNo match
と出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/14.txt
として実行します。プログラムはSeverus
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/15.txt
として実行します。プログラムはSirius
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/16.txt
として実行します。プログラムはNo match
と出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/17.txt
として実行します。プログラムからHarry
が出力されます。 - プログラムを
python dna.py databases/large.csv sequences/18.txt
として実行します。プログラムはNo match
と出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/19.txt
として実行します。プログラムはFred
を出力するはずです。 - プログラムを
python dna.py databases/large.csv sequences/20.txt
として実行します。プログラムはNo match
と出力するはずです。
check50
を使用して以下を実行し、コードの正確さを評価してください。ただし、コンパイルとテストは必ず自分で行ってください。
check50 cs50/problems/2021/x/dna
以下を実行し、style50
を使用してコードのスタイルを評価します。
style50 dna.py
提出方法
次のコマンドを実行し、GitHubのユーザー名とパスワードを入力してログインします。セキュリティのため、パスワードには実際の文字ではなくアスタリスク (*
) が表示されます。
submit50 cs50/problems/2021/x/dna