遊べるJavaScript入門ロゴ

わからないことが次々でてくるJavascript

コードが間違っていないはずなのに「動いてくれない」などで Javascriptのプログラムの頑固さに悩まされたことがありませんか。

私の場合のよくある原因は単純な「タイプミス」が意外に多いのですが、大文字と小文字の間違い、2バイト文字(日本語)が入り込む場合、半角スペースに全角スペースが入り込むなどは見つけにくので、結構、些細なミスで苦労します。

タイプミスは、無料エディターの「Visual Studio Code」を使うと、多くのエラーを防いでくれるので、タイプミス自体は少なりますが、完全に動くようになるのをサポートしてくれませんから、動くまで試行錯誤だけです。

例えば、少し手を広げようとすると、関数の意味などを充分に知らないことで行き詰まったり、基礎の「変数の重複」「宣言の問題」などが理解できていないことでうまく動いてくれないなどで、Javascriptにはいろいろ悩まされます。

意外に、基礎的なことの理解が大変難しく、例えば、最初に「変数の宣言」をする場合でも、「var」がいいのか「const」がいいのかもまだ理解できておらず、初心者なのでよくわからないので、何も考えないで「let」を使っているという状態ですが、Varに変えると動いた… というのは、やはり、基礎ができていないからなのでしょう。

WEBで、通常の変数は[let」、定数は「const」、動きがおかしかった等「var」にしているという記事がありましたが、少し慣れた人でも苦労しているというのは、多機能で優秀であっても、いいプログラム言語ではないのかもしれませんが、ついていくしか仕方がありません。

私が書いているのは短いプログラムですから、道中はともかく、「動けば良し!」ということですべてを割り切るようにしていると、結構楽しめます。

このHPは、こんな初心者が書いていますから、細かい検討はされていませんが、きっちりと動きますから、これを参考に、自分でアレンジしていただくと結構楽しめますよ。

PR

ここで、私が悩んだ例を紹介します。 

乱数Math.random()関数 を使ってプログラムを書いたのですが、「何か」結果がおかしいと3日間も悩んだものですが、こんなこともあるという程度に読んでください。


ランダム関数Math.random()は便利な関数

私のHP記事でもよく使う関数で、サイコロをふって「丁か半か?」を出したり、サイコロも目がいくつなのか……などに乱数を作る関数「Math.random()」があります。

このMath.random()は 0から1までの乱数を出してくれるので、丁か半かを決める場合は、得られた乱数を2倍して1を足し、サイコロの目であれば、6倍して1を足してから小数部分の処理を切り捨て、四捨五入、切り上げをすればいいはずですが、私がはまり込んだ問題はちょっと大変でした。

うまくいかなかった原因は、関数の定義を詳しく知らなかったためです。

切り捨てで処理すると1~6の目になるのが、四捨五入や切り上げをすると、(プログラムでは見えてこない) 7の目が出てしまっていたという異常に気づかなかったのですが、それがわかるまでに時間がかかりました。 下がそれです。


サイコロを100回振るときの小数点処理での違い

Javascriptのプログラムは、ページを開いた時点で動いています。 だから、たとえばこの記事を見ているときには、すでに、プログラムが動いて、処理された結果は下に表示されています。

そこで、このページのずっと下にある2つの結果の違いを見てください。 切り捨てと四捨五入で、合計数が違うのです。 (再計算させたい場合は、「ページの再読み込み」をすれば、新しい結果が表示されます) 

これは、サイコロをふって1~6の目が100回でどのような分布になるのかを見ています。小数以下を切り捨てる場合の正常に動くコードは次のようなものです。(青字部分)

let one=0,two=0,three=0,four=0,five=0,six=0;   //最初はすべて0
for (let i=1; i<=100; i++) {     //100回繰り返します
let sai2 =Math.floor(Math.random()*6+1);    //【計算】1~6の目を出します
switch (sai2) {     //出た目を1~6に振り分けて合計します
case 1:       // 1の目の場合
one = one+1;
break;
case 2:
two= two+1;
break;
case 3:
three= three+1;
break;
case 4:
four= four+1;
break;
case 5:
five =five+1;
break;
case 6:
six= six+1;
break;
}
}
        //ここから、1~6の合計を書き出します。
        //正しく改行するためのオマジナイ<pre>~</pre>を入れています
document.writeln('<pre>');
document.writeln('100回サイコロを振ってそれぞれの目の出る数を数えました。');
document.writeln('1は ' + one + ' こです。');
document.writeln('2は ' + two + ' こです。');
document.writeln('3は ' + three + ' こです。');
document.writeln('4は ' + four + ' こです。');
document.writeln('5は ' + five + ' こです。');
document.writeln('6は ' + six + ' こです。');
document.writeln('</pre>');
document.close(); 

メインは3行目の【計算】と書いた部分で、四捨五入の場合には、「floor」を「round」にすればいいのですが、それで動かしてみると、下の結果のように変な数字になります。

100回繰り返しているのに、合計が100になりません。つまり、実際には7の目がでていて、ここではそれが表示されないので合計数は100より少ないのです。

これは、【計算】の行の下に、document.write(sai3)の1行を加えて、毎回の計算結果を書き出してみて問題点が見つかったのですが、これは現在は使ってはいけないメソッドなので、console.log() を使って途中の計算結果を確認する方法でもいいでしょう。

PR

このように、Javascriptは、動いていればいいといっても、それが、正常な動きかどうかもわかりにくいですから、自分で「何かしてやろう」としても、完璧にするにはかなりハードルが高くなってしまいます。

**********Javascriptはここから(計算はすでに完了しています)

切り捨てMath.floorの場合 正常

四捨五入Math.roundの場合 合計が変?

*********Javascriptはここまで

(お断り)このページでは、「コピー」ができませんので、コピーは、画面を右クリックして、「ページのソースを表示」させてHTMLからコピーしてください。

ランダムな数値は、均一にバラバラになっていない

よく引き合いに出される話ですが、「丁」が連続して10回続いているので、次は「半の確率が高い!」とか、ルーレットの黒が続いているので赤に賭けるほうが正解……という考え方はある意味では正しそうですが、丁か半かの確率は、毎回0.5(二分の一)なのです。

つまりそれが「いつ出るのか」で賭けが成立しているのです。

サイコロを1万回ふらせてみると、「丁か半か」は半々に近づくはずで、これも簡単に確認できますから後で紹介するとして、まず、上のプログラムで5回繰り返して、それぞれの目が出る数字を手書きで書き出してみました。(これは、このプログラムで実行したものを集計したもので、あくまでも1つの例です)

サイコロを振った目の出方の例

このように、100回サイコロをふると、100/6≒16.7回という平均でサイコロの目が出てもいいのですが、実際には均等ではなく、目によってかなりの出現数に差があります。 

ここには示しませんが、5回500回の合計値をみると、最大最小で20回の出現数の幅があって、サイコロの各目の確率が1/6といっても、1/6にはなっていないのです。

これは繰り返し回数が100回の場合ですが、それを1万回、10万回にしてみるとどうでしょう。 やり方は、上のコードの中の「for文にある100」を10000や100000にするだけです。

これも、あっという間にコンピュータは計算してくれます。

この結果をみると(これも1つの例ですが)、100回では最大・最小回数の差が9であったものが、100倍の1万回では900ではなく111で、100の1000倍の10万回では(たった?)288 の差にしかなっていません。

数が多くなれば平均化されるということのようです。 これを計算させるのは簡単で、Script中の数字を書き換えてみて自分で確かめてみると面白いですよ。

「乱数はバラバラに数字が出現している」といわれる通りに、その「均一なバラバラさ」は折り紙付きですが、それがいつ出るのかがわからないから「賭け」が成り立っていつということですね。

そしてさらに、自分の「勘」や「思い込み」が加わると、さらに賭けをエクサイトさせるのですが、根本的には、10回続いたサイコロゲームで、丁の次に半になる確率はやはり 1/2 なのですが、そこに10回連続して丁になるという「数字の神秘性」も加わるのが「偶然と確率」の面白いところですね。 

ランダムや確率という科学と、役に立つかどうかわからない「勘」とが賭けをさらにヒートアップさせるから面白さが加わるのですが、このような「数」の遊びもJavascriptを使って楽しむこともできるのです。

そのJavascriptですが、他のプログラム言語も学んだことはありませんが、独特の書き方は、やはりどこか馴染みにくいものです。 

英字圏で開発されたものなので、日本人にはわかりにくいものになっているのかもしれません。 しかし、気ままに気楽にやっていると、「ボケ防止」「頭の体操」になっている感じもしますので、楽しむ程度に限定しておけば楽しめそうですので、少し続けてみようと思っています。

 

記事の目次へ

PR



(来歴)R6.5作成  
PR

AmazonのJavascript本 送料無料


楽天ブックスは品揃え200万点以上!



記事の目次へ

電子工作の記事の目次へ