プログラミング 中部大学2025年春期

Javascriptによるプログラミング6

塩基を数える

DNAの塩基配列に含まれる4つの塩基をそれぞれ数えるプログラムを作成する。

塩基を数える関数を定義する

まず関数を定義する。 関数ができるまではページを更新すると自動的に実行されるようにする。 動作確認がしやすいように計算対象の塩基配列は予め変数にいれておく。 結果はdocument.writeで表示してもいいが、コードが長くなって面倒なので、console.logでデベロッパーツールのConsoleに表示されるようにする。

<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--

/*
 *	塩基を数える関数 countnuc を定義する。引数のseqに塩基配列が入る。
 */
function countnuc(seq){
	console.log(seq);	//	ブラウザーのConsoleに出力する。document.writeとするよりも簡単に変数をチェックできる。
}

var test_seq = 'AACCGT';	//	関数の動作確認用の塩基配列
countnuc(test_seq);	//	関数を呼び出す

--></script>
</body>
</html>
実行結果

bodyタグの中に何も出力していないので、ブラウザーでは何も表示されていないように見える。 console.logはデベロッパーツールのConsoleに出力する関数で、図のConsole(青下線)をクリックするとAACCGTが見える。 プログラムの開発中は変数の値を適宜コンソールに出力するようにすると開発がしやすい。

関数の中身をつくる1

<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--

/*
 *	塩基を数える関数 countnuc を定義する。引数のseqに塩基配列が入る。
 */
function countnuc(seq){
	var count = [0, 0, 0, 0];	//	ACGTの個数をいれる配列を初期化する。Aの数を0番目、Cの数を1番目にいれることにする。
	console.log(seq.length);	//	変数seqに含まれる文字数を調べるにはlengthプロパティを調べる。
					//	変数に.lengthとつけるとそれ全体で文字数になる。
	console.log(seq.substr(0, 1));	//	部分文字列を取得するにはsubstrメソッドを使う。
					//	変数seqの0番目から1文字を取り出すには.substr(0, 1)をつける。
	
	for(var s = 0 ; s < seq.length ; s ++){
		var N = seq.substr(s, 1);	//	 変数Nに1文字入れる。
		console.log(N);	//	文字列が1つずつになっていることを確認する。
	}
}

var test_seq = 'AACCGT';
countnuc(test_seq);

--></script>
</body>
</html>
実行結果

Consoleの1行目の6がseq.lengthで取得された変数seqの文字数。 2行目のAはseq.substr(0, 1)で取得された変数seqの1文字目。 以降はseqを1文字ずつ出力した結果(同じものが続くときはまとめられている)。

関数の中身をつくる2

<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--

/*
 *	塩基を数える関数 countnuc を定義する。引数のseqに塩基配列が入る。
 */
function countnuc(seq){
	var count = [0, 0, 0, 0];
	
	for(var s = 0 ; s < seq.length ; s ++){
		var N = seq.substr(s, 1);	//	 変数Nに1文字入れる。
		if('A' == N){
			count[0] ++;
		}else if('C' == N){
			count[1] ++;
		}else if('G' == N){
			count[2] ++;
		}else if('T' == N){
			count[3] ++;
		}
	}
	console.log(count);	//	数え終わったもののチェック
	return count;
}

var test_seq = 'AACCGT';
countnuc(test_seq);

--></script>
</body>
</html>
実行結果

seq.substr(s, 1)で取り出した1文字を比較して、該当するcount配列の要素を増やす。 値を返す前にConsoleで配列を確認する。

集計結果を表示する表を作る

塩基の数を示す表をつくる。 数をJavascriptで操作しやすいようにinputでつくる。

<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--

/*
 *	塩基を数える関数 countnuc を定義する。引数のseqに塩基配列が入る。
 */
function countnuc(seq){
	var count = [0, 0, 0, 0];
	
	for(var s = 0 ; s < seq.length ; s ++){
		var N = seq.substr(s, 1);	//	 変数Nに1文字入れる。
		if('A' == N){
			count[0] ++;
		}else if('C' == N){
			count[1] ++;
		}else if('G' == N){
			count[2] ++;
		}else if('T' == N){
			count[3] ++;
		}
	}
	return count;
}

var test_seq = 'AACCGT';
countnuc(test_seq);
--></script> <!-- ここで一旦Javascriptを抜ける	-->

<table>
	<thead><tr><th>塩基</th><th>数</th></tr></thead>
	<tbody>
	<script type='text/javascript'><!--
		//	4行似たものを繰り返すので再びJavascriptを書く
		var N = ['A', 'C', 'G', 'T'];
		for(var n = 0 ; n < N.length ; n ++){
			//	以下は <tr><td>A</td><td><input type='input' id='A'></td></tr> を出力する
			document.write("<tr><td>" + N[n] + "</td><td><input type='input' id='" + N[n] + "'></td></tr>");
		}
	--></script>
	</tbody>
</table>
</body>
</html>
実行結果

表の値を書き換える

Javascriptから表の値を書き換える。 これは表が出力されてから実行する必要があることに注意する。

<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--
/*
 *	塩基を数える関数 countnuc を定義する。引数のseqに塩基配列が入る。
 */
function countnuc(seq){
	var count = [0, 0, 0, 0];
	
	for(var s = 0 ; s < seq.length ; s ++){
		var N = seq.substr(s, 1);	//	 変数Nに1文字入れる。
		if('A' == N){
			count[0] ++;
		}else if('C' == N){
			count[1] ++;
		}else if('G' == N){
			count[2] ++;
		}else if('T' == N){
			count[3] ++;
		}
	}
	return count;
}
--></script> <!-- ここで一旦Javascriptを抜ける	-->

<table>
	<thead><tr><th>塩基</th><th>数</th></tr></thead>
	<tbody>
	<script type='text/javascript'><!--
		//	4行似たものを繰り返すので再びJavascriptを書く
		var N = ['A', 'C', 'G', 'T'];
		for(var n = 0 ; n < N.length ; n ++){
			//	以下は <tr><td>A</td><td><input type='input' id='A'></td></tr> を出力する
			document.write("<tr><td>" + N[n] + "</td><td><input type='input' id='" + N[n] + "'></td></tr>");
		}
	--></script>
	</tbody>
</table>
<script type='text/javascript'><!--
//	表が出力された後で実行する必要があるので、再びJavascriptを書く	
var test_seq = 'AACCGT';
var count = countnuc(test_seq);
console.log(count);	//	関数の戻り値をチェック
document.getElementById('A').value = count[0];	// Aの数をテキストボックスの値に設定する
--></script>
</body>
</html>
実行結果

ユーザーが塩基配列を入力する

ユーザーの入力を受け取るテキストボックスをつくる。 動作確認のためにvalue属性に塩基配列を設定しておけば、ボタンをクリックするだけでJavascriptを確認できる。

<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--
//	塩基を数える関数 countnuc を定義する。引数のseqに塩基配列が入る。
function countnuc(seq){
	var count = [0, 0, 0, 0];
	
	for(var s = 0 ; s < seq.length ; s ++){
		var N = seq.substr(s, 1);	//	 変数Nに1文字入れる。
		if('A' == N){
			count[0] ++;
		}else if('C' == N){
			count[1] ++;
		}else if('G' == N){
			count[2] ++;
		}else if('T' == N){
			count[3] ++;
		}
	}
	return count;
}

//	ボタンをクリックしたときに呼ばれる関数
function runCount(){
	//	ユーザーの入力値を変数にとる
	var seq = document.getElementById('seq').value;
	//	関数を呼び出して塩基を数える
	var count = countnuc(seq);

	// 塩基数を表示する。配列Nはこれより後ろで定義されているが、実行されるのはここのほうが後なので使用できる。
	for(var n = 0 ; n < N.length ; n ++){
		document.getElementById(N[n]).value = count[n];	// Aの数をテキストボックスの値に設定する
	}
}

--></script> <!-- ここで一旦Javascriptを抜ける	-->
<div>
	塩基の組成を調べたい配列を入力してください。
	<input type='input' value='AACCGT' id='seq'>
	<input type='button' value='塩基を数える' onclick='runCount()'>
</div>
<table>
	<thead><tr><th>塩基</th><th>数</th></tr></thead>
	<tbody>
	<script type='text/javascript'><!--
		//	4行似たものを繰り返すので再びJavascriptを書く
		var N = ['A', 'C', 'G', 'T'];
		for(var n = 0 ; n < N.length ; n ++){
			//	以下は <tr><td>A</td><td><input type='input' id='A'></td></tr> を出力する
			document.write("<tr><td>" + N[n] + "</td><td><input type='input' id='" + N[n] + "'></td></tr>");
		}
	--></script>
	</tbody>
</table>
</body>
</html>
実行結果

FASTA形式の塩基配列を処理する

塩基配列の書式としてFASTAというものが広く使われている。 FASTA形式では塩基配列の名前を>で始まる先頭行に書き、以降塩基配列を複数行に分けて書くことができる。 以下に例を示す。

FASTAの塩基配列をコンピュータで処理するには途中で改行されていることが邪魔になるので、それを除いてコンピュータに適した形に変換する。

ユーザーが塩基配列を入力するフォームをつくってその値を読み込む

textareaをユーザーの入力を受け取るテキストボックスをつくる。 テキストエリアの値も.valueプロパティで取得できることを確認する。

<!DOCTYPE HTML>
<html>
<body>
<h4>塩基配列をFASTA形式で入力してください</h4>
<textarea id='seq'>
>chr_03q
ATGTCTTATATGCTTCCACATTTAACCAATGGCTGGCAAGTAGATCAGGCCATTCTGAAT
GAGCAAGAACGAGTTGTTGTCATTCGTTTTGGCCATGATTGGGACCCCGCTTGCATGACG
ATGGACGAAACTCTTTACAGCATCGCAGACAAAGTGAAAAACTTTGCGGTCACATACCTC
GTTGATATTACAGAGGTTCCTGATTTTAACAAGATGTACGAACTTTATGACCCCTGCACG
ACCATGTTTTTTTATCGGAACAAACACATTATGATTGATTTAGGAACTGGTAACAACAAC
AAAATCAATTGGCCAATGGAGGATAAACAAGAAATGATTGATATTCTAGAAACAATTTAT
CGCGGCGCAAGGAAGGGAAGAGGTCTGGTAGTTTCGCCAAAAGATTATTCCACAAAATAT
AGATAT
</textarea>
<script type='text/javascript'><!--
var seq = document.getElementById('seq').value;	//	テキストエリアの値もvalueで取得できる。
console.log(seq.length);	//	変数にはいったことを確認(全部出力すると長くなるので長さで代用)。
--></script>
</body>
</html>
実行結果

塩基配列を一行ごとに分割する

splitメソッドは引数の文字を区切りとして文字列を分割することができる。 分割された文字列は配列になって返る。

<!DOCTYPE HTML>
<html>
<body>
<h4>塩基配列をFASTA形式で入力してください</h4>
<textarea id='seq'>
>chr_03q
ATGTCTTATATGCTTCCACATTTAACCAATGGCTGGCAAGTAGATCAGGCCATTCTGAAT
GAGCAAGAACGAGTTGTTGTCATTCGTTTTGGCCATGATTGGGACCCCGCTTGCATGACG
ATGGACGAAACTCTTTACAGCATCGCAGACAAAGTGAAAAACTTTGCGGTCACATACCTC
GTTGATATTACAGAGGTTCCTGATTTTAACAAGATGTACGAACTTTATGACCCCTGCACG
ACCATGTTTTTTTATCGGAACAAACACATTATGATTGATTTAGGAACTGGTAACAACAAC
AAAATCAATTGGCCAATGGAGGATAAACAAGAAATGATTGATATTCTAGAAACAATTTAT
CGCGGCGCAAGGAAGGGAAGAGGTCTGGTAGTTTCGCCAAAAGATTATTCCACAAAATAT
AGATAT
</textarea>
<script type='text/javascript'><!--
var seq = document.getElementById('seq').value;	//	テキストエリアの値もvalueで取得できる。
var lines = seq.split("\n");	//	改行で文字列を分割する。一行ごとに配列にはいる。
console.log(seq, lines);	//	取得した文字列と、split後のデータを比較する。
--></script>
</body>
</html>
実行結果

先頭行と配列本体を分ける

>で始まる文字は配列の名前なので塩基配列とは別に扱う。 >で始まらない行は塩基配列として結合する。

<!DOCTYPE HTML>
<html>
<body>
<h4>塩基配列をFASTA形式で入力してください</h4>
<textarea id='seq'>
>chr_03q
ATGTCTTATATGCTTCCACATTTAACCAATGGCTGGCAAGTAGATCAGGCCATTCTGAAT
GAGCAAGAACGAGTTGTTGTCATTCGTTTTGGCCATGATTGGGACCCCGCTTGCATGACG
ATGGACGAAACTCTTTACAGCATCGCAGACAAAGTGAAAAACTTTGCGGTCACATACCTC
GTTGATATTACAGAGGTTCCTGATTTTAACAAGATGTACGAACTTTATGACCCCTGCACG
ACCATGTTTTTTTATCGGAACAAACACATTATGATTGATTTAGGAACTGGTAACAACAAC
AAAATCAATTGGCCAATGGAGGATAAACAAGAAATGATTGATATTCTAGAAACAATTTAT
CGCGGCGCAAGGAAGGGAAGAGGTCTGGTAGTTTCGCCAAAAGATTATTCCACAAAATAT
AGATAT
</textarea>
<script type='text/javascript'><!--
var seq = document.getElementById('seq').value;	//	テキストエリアの値もvalueで取得できる。
var lines = seq.split("\n");	//	改行で文字列を分割する。一行ごとに配列にはいる。
var header;		//	塩基配列の名前をいれる。
var joined = '';	//	結合の塩基配列をいれる変数
for(var l = 0 ; l < lines.length ; l ++){	//	lines.lengthは配列linesの要素数
	if('>' == lines[l].substr(0, 1)){
		header = lines[l].substr(1);	//	substrの二つ目の引数を省略すると最後までの文字列になる
	}else{
		joined = joined + lines[l];
	}
}
console.log(seq, lines, joined, header);	//	joinedは改行されていないことに注目
--></script>
</body>
</html>
実行結果

塩基を数える

先ほどの塩基を数えるプログラムのユーザーの入力値を読み取る部分をFASTA対応にする。

<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--
//	塩基を数える関数 countnuc を定義する。引数のseqに塩基配列が入る。
function countnuc(seq){
	var count = [0, 0, 0, 0];
	
	for(var s = 0 ; s < seq.length ; s ++){
		var N = seq.substr(s, 1);	//	 変数Nに1文字入れる。
		if('A' == N){
			count[0] ++;
		}else if('C' == N){
			count[1] ++;
		}else if('G' == N){
			count[2] ++;
		}else if('T' == N){
			count[3] ++;
		}
	}
	return count;
}

//	ボタンをクリックしたときに呼ばれる関数
function runCount(){
	var lines = document.getElementById('seq').value.split("\n");	//	テキストエリアの値を取得して改行で分割する。
	var header;		//	塩基配列の名前をいれる。
	var joined = '';	//	結合の塩基配列をいれる変数
	for(var l = 0 ; l < lines.length ; l ++){	//	lines.lengthは配列linesの要素数
		if('>' == lines[l].substr(0, 1)){
			header = lines[l].substr(1);	//	substrの二つ目の引数を省略すると最後までの文字列になる
		}else{
			joined = joined + lines[l];
		}
	}
	//	関数を呼び出して塩基を数える
	var count = countnuc(joined);

	// 塩基数を表示する。配列Nはこれより後ろで定義されているが、実行されるのはここのほうが後なので使用できる。
	for(var n = 0 ; n < N.length ; n ++){
		document.getElementById(N[n]).value = count[n];	// Aの数をテキストボックスの値に設定する
	}
}

--></script> <!-- ここで一旦Javascriptを抜ける	-->
<div>
	<h4>塩基の組成を調べたい塩基配列をFASTA形式で入力してください</h4>
<textarea id='seq'>
>chr_03q
ATGTCTTATATGCTTCCACATTTAACCAATGGCTGGCAAGTAGATCAGGCCATTCTGAAT
GAGCAAGAACGAGTTGTTGTCATTCGTTTTGGCCATGATTGGGACCCCGCTTGCATGACG
ATGGACGAAACTCTTTACAGCATCGCAGACAAAGTGAAAAACTTTGCGGTCACATACCTC
GTTGATATTACAGAGGTTCCTGATTTTAACAAGATGTACGAACTTTATGACCCCTGCACG
ACCATGTTTTTTTATCGGAACAAACACATTATGATTGATTTAGGAACTGGTAACAACAAC
AAAATCAATTGGCCAATGGAGGATAAACAAGAAATGATTGATATTCTAGAAACAATTTAT
CGCGGCGCAAGGAAGGGAAGAGGTCTGGTAGTTTCGCCAAAAGATTATTCCACAAAATAT
AGATAT
</textarea>
	<input type='button' value='塩基を数える' onclick='runCount()'>
</div>
<table>
	<thead><tr><th>塩基</th><th>数</th></tr></thead>
	<tbody>
	<script type='text/javascript'><!--
		//	4行似たものを繰り返すので再びJavascriptを書く
		var N = ['A', 'C', 'G', 'T'];
		for(var n = 0 ; n < N.length ; n ++){
			//	以下は <tr><td>A</td><td><input type='input' id='A'></td></tr> を出力する
			document.write("<tr><td>" + N[n] + "</td><td><input type='input' id='" + N[n] + "'></td></tr>");
		}
	--></script>
	</tbody>
</table>
</body>
</html>
<!DOCTYPE HTML>
<html>
<body>
<script type='text/javascript'><!--
--></script>
</body>
</html>
実行結果

課題

塩基配列の相補鎖を出力するHTML & Javascriptを作成せよ。 例えばAACTAGGTという塩基配列を入力したとき、ACCTAGTTという配列を表示する。

ボタン一つで相補鎖変換

作成手順

Scratchでつくるとこんな感じ

課題のテスト

以下の塩基配列を相補鎖に変換してみてください。それぞれ正解を右に示します。

テスト値正解
レベル1
レベル2
レベル3