memorandums

日々のメモです。

GAS (Google App Script) のparseIntでドハマリした件

新学期が始まりました。

今年度の担当講義で、1つの試行として、この講義を真似して、講義中にちゃんと聞いていることを確認するため(寝させないため)、授業中にクイズを差し込んでみています。

クリッカーシステムがないので、これまでも利用したことがあるGoogle Formsでやってみたのですが、授業中にいちいちQRコードを読ませるのは効率が悪かったんですね。。。

そこで、Google App Script(以降GASと略)で簡単なWebアプリが作れるらしいので、Fusion Tableという簡易DBと組み合わせてクリッカーシステムを作り試験運用を始めています。

とりあえず集計して課題点として評価するために、GoogleスプレッドシートとGASを使って簡単な集計プログラムを作っていました。

で、やっと本題です。

クリッカーシステムでは学生番号を手入力させるのですが、面倒くさくないように、現役生は下2桁だけ入力するように、再履修生はフル桁で入力するように指示しています。それでも、よく聞いていない現役生がフル桁で入力する者がいたり。。。

そこで前処理として、現役生であれば前処理するようにしてみました。

学籍番号は「入学年度学科コード0001」という感じです。下2桁なら「1」でいいわけです。

とりあえず「入学年度学科コード」が邪魔なのでreplaceメソッドで取り除きます。よくある手です。

id = 入力された学籍番号.replace("入学年度学科コード",  "");

で、これで「"0001"」という文字列が得られますので、parseIntを使って整数化してゼロを除去しようとしました。

id = parseInt(id);

すると。。。なぜか結果がおかしい。。。


文字列を整数化すると1桁の数値は問題ないけと60以上の番号は他の数字に置き換わります。。。不思議。サンプルは以下のような感じでした。わかります?これで何が悪いか?

3 → 3
7 → 7
64 → 52
68 → 6

ここから調べること1時間位。。。いろいろとデバッグしてみた結果、parseIntの動きが怪しいことがわかりました。で、JSのドキュメントでparseIntを調べると、0始まりの文字列は8進数になる。。。という情報が。そういうこともありましたが。。。まさかここに効いてくるとは。

上記のコードを以下のようにしてみました。2番めの引数が基数になります。これでうまく結果が表示されました。

id = parseInt(id, 10);

64は確かに8進数では52になりますが、68が6になるのは意味がわかりません。バグか?

ちなみにローカルでnodeで確かめてみたんですが、nodeのparseInt("0064")もparseInt("0068")も単純に0を除外した整数にすることができました。。。

Googleのドキュメントを調べてみたのですが、parseIntの解説がなく。。。

最近、GASの本が発刊されて再燃?しているように思います。

もし、同じような仕様を実装するときには注意されたほうがいいと思います。はい。

もう終わりますが、praseIntで実験してみました。以下がテストプログラムです。

function myFunction() {
  for (var i=0; i<100; i++)
  Logger.log(parseInt("0" + i))
}

そして、以下が実行ログ。なんだろ。。。これ?仕様なのかな?バグなのかな?

0.0
1.0
2.0
3.0
4.0
5.0
6.0
7.0
NaN
NaN
8.0
9.0
10.0
11.0
12.0
13.0
14.0
15.0
1.0
1.0
16.0
17.0
18.0
19.0
20.0
21.0
22.0
23.0
2.0
2.0
24.0
25.0
26.0
27.0
28.0
29.0
30.0
31.0
3.0
3.0
32.0
33.0
34.0
35.0
36.0
37.0
38.0
39.0
4.0
4.0
40.0
41.0
42.0
43.0
44.0
45.0
46.0
47.0
5.0
5.0
48.0
49.0
50.0
51.0
52.0
53.0
54.0
55.0
6.0
6.0
56.0
57.0
58.0
59.0
60.0
61.0
62.0
63.0
7.0
7.0
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN