【JavaScript】ワクチン効果を確かめるプログラムのソースコード解説

前回,ワクチン接種によるウイルス感染者数の推移を計算してみる【プログラミング入門】で紹介したプログラムのソースコードの解説をします。

必要な知識をすべて解説すると膨大な量になるので,細かい部分についてはネットで検索してみましょう。今回はプログラムに初めてチャレンジする中高生向けに,コードがどのような仕組みで動いているかに絞って解説していきます。

まずは,コード全体を示します。

<!DOCTYPE html><html><body><script>

  let shinki = [100];     //1日目の新規感染者は100人
  let kaihuku = [0];      //回復者数
  let kansensha = [100];  //感染者数
  const denpa = 0.15;     //ウイルスを伝播させる確率
  const waku = 0;           //ワクチン接種率

  document.write('<table>');
  document.write('<tr><td>日</td><td>新規</td><td>回復</td><td>患者数</td></tr>');

  for(let i = 0; i < 121; i++) {

    if( i > 58 ) {
      shinki.push(Math.round(kansensha[i]*denpa*(1-waku)));
    } else {
      shinki.push(Math.round(kansensha[i]*denpa));        
    };

    if( i > 12 ) {
      kaihuku.push(shinki[i-13]);
    } else {
      kaihuku.push(0);
    };

    kansensha.push(Math.round(kansensha[i]+shinki[i+1]-kaihuku[i+1]));
    document.write('<tr>');
    document.write('<td>'+(i)+'</td>');
    document.write('<td>'+shinki[i].toLocaleString()+'</td>');
    document.write('<td>'+kaihuku[i].toLocaleString()+'</td>');
    document.write('<td>'+kansensha[i].toLocaleString()+'</td>');
    document.write('</tr>');
  };
      
  document.write('</table>');
  document.write('<p>計算終了</p>');

</script></body></html>

コードを書くために必要なもの

コードを書くのに必要なものはテキストエディタです。windows の場合はメモ帳があるので,それを使うことができます。もっと本格的にコードを書きたい場合は無料で使える Visual Studio CodeAtom をインストールすると良いでしょう。はじめはメモ帳で十分です。

コードを書いたら,ファイル名をたとえば test.html のように拡張子を .html として保存します。こうすることで,エクスプローラーで保存したファイルをダブルクリックするだけで,ブラウザ上でプログラムが動作します。

今回は Javascript でプログラムを動作させていますが,Javascript はとりあえずプログラムを動かす上で専用のツールを必要とせず,すぐに結果を確かめることができる点で優秀です。また,Javascript は web アプリなどの開発で実際に使われている言語であるため,みなさんがコンピューターを扱う仕事に就職したときにもちゃんと使える言語である点も魅力的でしょう。

html と Javascript

このコードは全体としては html という言語で書かれています。そして html の中に Javascript という別の言語が挿入されている形になっています。

html は要素をタグによって囲む仕組みです。このコードは <html></html>というタグで囲まれていて,タグの間にある文字は html 言語であることを示しています。

コードを上から順番に見ていきましょう。

<!DOCTYPE html><html><body><script>

<!DOCTYPE html> は,この文章が html 言語であることを宣言するものです。

<body></body>は,実際に画面上に表示する文字などを記述する部分です。例えば,<body>ああああ</body>などと書くと,画面上に「ああああ」と表示されます。

そして,さらにその中に<script></script>で囲まれた部分があります。ここが JavaScript 言語の部分です。<script>タグで囲むことで,html 言語の中に JavaScript という別の言語を書くことができるのです。

html 言語の中に JavaScript 言語を挿入するのは,html 言語は計算などの作業を行うことができないからです。html はあくまで画面上に文字や画像を表示するための言語なので,計算などの作業は JavaScript で行う必要があるのです。

変数の宣言

では<script></script></script>で囲まれた部分,JavaScript 言語の記述を見ていきましょう。

  let shinki = [100];     //1日目の新規感染者は100人
  let kaihuku = [0];      //回復者数
  let kansensha = [100];  //感染者数
  const denpa = 0.15;     //ウイルスを伝播させる確率
  const waku = 0;         //ワクチン接種率

ここで行っていることは変数の宣言です。数学では $x$ や $y$ に数字を代入しますが,同じように shinki denpa という文字に値を代入しています。プログラミングの世界ではこれを変数と言います。変数の名前は自分で自由に決めることができます。

ただし,最初に let shinki と書くことで shinki という文字が変数であることを宣言しておく必要があります。こうすることでコンピューターは今後 shinki という文字を値を代入できる文字として認識することになるのです。

const denpa = 0.15; の場合は,denpa という文字が定数であることを宣言しています。let の場合はあとから代入する値をいろいろ変えることができますが,const の場合はあとから値を変更することはできません。変数と定数を分けるのは,プログラムの誤作動を防いで,コードを読む人が情報を整理しやすくする意味があります。

配列の考え方

ところで  let shinki = [100]; では変数に代入する値が [ ] で囲まれています。これは変数が配列であることを示しています。

配列とは,要するに高校数学IIBで習う数列のことです。shinki=[100] は $a_{0}=100$ と同じことです。数列 $a$ が数列 shinki になったと考えればよいでしょう。

例えば let shinki = [100,200]; と書けば,$a_{0}=100$,$a_{1}=200$ を意味します。ここでは配列の宣言と代入が同時に行われています。

また,そのあとで配列に値を代入するときは shinki[0]=200; のように書きます。これは $a_{0}=200$ と同じことです。数列の初項は 1 から始めますが,配列の初項は 0 から始まります。

doument.write() で文字を出力する

  document.write('<table>');
  document.write('<tr><td>日</td><td>新規</td><td>回復</td><td>患者数</td></tr>');

document.write('文字'); は文字を画面に表示させる命令文です。たとえば,document.write('Hello'); とすると,画面上に Hello という文字が表示されます。ここでは,文字の代わりに html 言語のタグが書かれています。

<table></table> は表を表示するタグです。例えば

<table>
  <tr>
    <td>1</td>
    <td>2</td>
  </tr>
  <tr>
    <td>3</td>
    <td>4</td>
  </tr>
</table>

とすると

12
34

このように,表の形式で文字が表示されます。

タグを用いることで単に文字を表示するだけでなく,表などのさまざまな形で表現することができようになります。

for() で繰り返し計算

  for(let i = 0; i < 121; i++) {

for 構文は繰り返しの処理を行います。詳しい説明は省きますが,ここでは i という変数が 0 から 120 まで変化しながら,{} の間で 121 回の繰り返しを行います。今回,i は日数を表しています。

if () で条件によって処理を分ける

    if( i > 58 ) {
      shinki.push(Math.round(kansensha[i]*denpa*(1-waku)));
    } else {
      shinki.push(Math.round(kansensha[i]*denpa));        
    };

    if( i > 12 ) {
      kaihuku.push(shinki[i-13]);
    } else {
      kaihuku.push(0);
    };

if 構文は「もし~なら」という意味です。ここでは i が 58 を超える,つまり i の値が 59 以上なら { } で囲まれた処理を実行するということです。else は逆に i が 58 を超えない場合に実行する処理を書きます。

shinki.push() は,配列である shinki に新しい値を加えることを意味します。配列に新しく Math.round(kansensha[i]*denpa*(1-waku)) が加えられます。数列で言うなら $a_{n+1}=a_n$×伝播率×(1-ワクチン接種率) と同じことです。

Math.round() はカッコの中の値を四捨五入して整数にする命令です。例えば,x = Math.round(5.102) なら x に代入される値は 5 で,x = Math.round(5.782) なら x に代入される値は 6 になります。

四捨五入される値は kansensha[i]*denpa*(1-waku) です。*は掛け算の×の意味です。kansensha[i] は日数 i における感染者数を表します。

たとえば,配列の100番目の感染者数が1万人で伝播率が0.15,ワクチン接種率が0.2なら,10000×0.15×(1-0.2)=10000×0.15×0.8=1200 となり,配列の101番目の値に 1200 が代入されることになります。

else の部分は shinki.push(Math.round(kansensha[i]*denpa));  となっており,日数 i が 0 から 58 の間は,ワクチン接種者がいないのでワクチン接種によるかけ算を行わないことになります。日数 i が 59 になったときに初めて,日数 i = 60 にワクチン接種率を考慮した値を代入するわけです。よって i = 59 の値にはワクチン接種率を考慮した値は代入されません。

2 つ目の if 文では,i が 12 を超えたとき,つまり i が 13 ならば回復者 kaihuku の 14 番目に新規感染者 shinki の 0 番目の値が代入されます。i が 12 を超えないときは 0 が代入されます。

    kansensha.push(Math.round(kansensha[i]+shinki[i+1]-kaihuku[i+1]));

これは数列で言えば,$a_{n+1}=a_n+$新規感染者-回復者 という計算です。

結果を出力する

    document.write('<tr>');
    document.write('<td>'+(i)+'</td>');
    document.write('<td>'+shinki[i].toLocaleString()+'</td>');
    document.write('<td>'+kaihuku[i].toLocaleString()+'</td>');
    document.write('<td>'+kansensha[i].toLocaleString()+'</td>');
    document.write('</tr>');

計算した結果を表形式で画面に出力する部分です。配列のうしろに .toLocaleString() を加えると数字にカンマが入り,1234 が 1,234 と表示されます。

最後にタグを閉じる

  };
      
  document.write('</table>');
  document.write('<p>計算終了</p>');

</script></body></html>

最後にタグを閉じていきます。一応計算が終了したことを表示する文も入っています。

配列を使うことで,たくさんのデータが並んだ数列を扱うことができます。今回は登場しませんが,二次元配列というものを使えば群数列を扱うこともできます。