コンピュータ36ページ目の日記です

目次

前のページ
2019-09-24 Google Asistant
2019-10-09 MVNOをMNP
2019-10-23 メールの1行が78文字の理由
2019-11-17 イベント終わりました
2019-11-19 遊びプログラム
2019-11-20 久しぶりのperl
2020-01-16 mysql で varchar を int に alter table する。
2020-02-16 MacBook Pro 購入
2020-02-22 node-tyrant のバグ修正
2020-02-27 BABA IS YOU
2020-04-15 【訃報】ジョン・ホートン・コンウェイ氏
2020-05-21 Chromebook を買ったのだけど
2020-06-19 ENIAC vs 6502
2020-07-17 phpSpreadsheet で小数点付き数値と見なせる文字列を入力するとおかしくなる
2020-07-27 リングフィットアドベンチャー
2020-08-17 Windowを閉じるボタンの左右位置
2020-08-22 iPhone SE 購入
2020-08-22 Lenovo Ideapad C340 購入
Google Asistant  2019-09-24 13:41:02  コンピュータ 歯車

▲目次へ ⇒この記事のURL

以前に「P30 で、アラーム後の Google Asistant Routine が動作しない」と書いた。


昨日、アラームをセットしようとしたら、Google Asistant の設定画面が表示された。

あら、急に使えるようになったみたい。


Huawei の OS アップデートは、最終更新が8月後半で、OS のバグが治った、ということではないようだ。

Google Asistant をアラーム後に呼び出す機能は、Google 製の時計アプリの機能なのだけど、こちらの最終更新は7月24日のようだ。


…つまり、本当になんで急に使えるようになったのか不明。


心当たりは、「P30 に最近乗り換えたけど、なぜか Google Asistant 設定画面が表示されないよ」って、バグ報告を先日送った、ということくらい。


Google Asistant は、ネットワークと連携して動作する機能で、一部の設定はネットワーク側にある。

もしかしたら、ネットワーク側の個人設定がおかしくなっていて、バグ報告を受けて設定を修正したのではないかな…と思っている。




まぁ、なぜ表示されなかったのか、なぜ表示されるようになったのか、本当の原因はわからないが、動くのはありがたい。


朝、アラームで目を覚ました後に、今日の予定を喋ってくれるのは、忘れっぽい僕にとっては非常にうれしい機能なんだ。



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

歯車

関連ページ

P30 買った【日記 19/09/06】

別年同日の日記

03年 そういえば

13年 みどりの窓口開設日(1965)

15年 パラケルスス 命日(1541)

18年 運動会


申し訳ありませんが、現在意見投稿をできない状態にしています

MVNOをMNP  2019-10-09 10:53:17  コンピュータ 家族

▲目次へ ⇒この記事のURL

携帯電話会社を変えた。

電話番号は変わっていない。


今まで、僕は DMM Mobile を使っていた。

ちなみに、妻は BIGLOBE Mobile だった。


経緯は過去に書いているのだけど、もともと両方とも僕の名義で持っていた回線で、MVNO に MNP しようとしたら、「1人1社1回線」ルールに阻まれ、同じ会社にまとめられなかったのだ。



…念のため説明。

MVNO って、一般に「格安 SIM」と言われているやつね。


厳密にいえば、回線提供会社からまとめて安く「回線の使用権」を買い上げ、一般に小売りする業者が MVNO 。

回線自体はドコモや AU なので、品質は保証されている。


(Softbank は厳密な意味での MVNO には提供を行っていない。ただし、別ブランドの Y!mobile を持っており、そちらでは Softbank より安い料金で回線を提供している。)



そして、MNP とは、電話番号は維持したままで別の電話会社にサービスを移行する仕組み。

携帯電話会社間で共通の取り決めがあり、その手順に従えば、電話番号を変えずに会社を変えられる。


先日、ネットで調べものしていたら「データ専用 SIM に MNP した」というブログ記事を見つけてびっくりしたよ。

(データ専用 SIM は、音声用の電話番号とは全く異なる電話番号が付与されており、MNP できない。

 どうも、ブログ主は MNP を「電話会社を変えること」という認識で使っていたようだった)




さて、いつもの通りいきなり余談で話がそれている。


今の MVNO を契約したのは 4年ほど前で、その時には「1人1社1回線」ルールがあった。

しかし、今はこのルールが緩くなり、どこの MVNO 会社でも、複数回線を持てるようになっている。


DMM は合計で3回線、BIGLOBE は5回線まで持てる。

そして、当然ながら、会社をまとめると基本料部分が安くなる。


1か月ほど前に、スマホを買い替えた

これを機に、古いスマホは長男に渡すことにした。


玉突きで長男のスマホは長女に行く。

…が、まだ長女は小学生なので、必要な時に貸すことにして親の管理とする


とはいえ、1回線増やす必要がある。

我が家は5人家族なので、ゆくゆくは5回線必要になるだろう。


そこで、今僕が使っている DMM も解約して、BIGLOBE に寄せることにした。


DMM が楽天に買収され、新規ユーザーの募集をやめてしまった、という理由もある。

すでに回線を持っている人はサブ回線を増やすことはできるのだが、先行き不透明なら今見切りをつけてもよいだろう。


(ちなみに、今まで長男が使っていたスマホは、Sonet の 0-sim を使っている。月額 0円。

 塾などで単独行動で出かける際に、LINE で連絡を取れればよい、という用途なら、これで十分だったが、時々外出時に調べものをしようとして「遅くて使い物にならない」と言っていた。

 もうすぐ高校受験で塾も忙しくなり、外出機会も増えたので高速回線に変えてやろう、という親心)




妻は、BIGLOBE で一番安い、月 1Gbyte の通信量のプランを使っていた。


これを、通信量シェアで3回線に増やしたいのだが、一番安いプランではサブ回線は持てない決まりだった。

そこで、サブ回線が持てる中で一番安いプランである、月 3GByte にプラン変更する。



…SIM を申し込もうと思ったが、プラン変更は翌月を待たなくてはならず、プラン変更が終わらないと SIM を申し込めない。


そのため、スマホを買ったのは先月頭だったが、SIM を変えるのに1か月待たされたわけだ。



そして、月頭の「1日」は、DMM 側で各種集計が行われるために、プラン変更などの手続きができない。

いや、厳密にいえばできないのは午前中程度で、集計終了後はできるのだけど忘れていた。


2日になってから DMM で MNP 転出の申し込み。

転出予約番号が発行されるまで、2~4日ほどお待ちください、となっている。


…それほどは待たず、3日の夜中に発行されていた、ようだ。

気づいたのは4日の朝だったのだけど。


4日に、BIGLOBE 側に MNP 転入の申し込み。

あと、子供用にデータ SIM を申し込む。


音声用は4~6日、データ用は2~4日ほどで家に届くという。


…両方まとめて、6日、日曜日に届いた。全体に仕事が速いよね。




僕の端末の SIM を入れ替え、BIGLOBE の WEB ページから「MNP 切り替え」の指示を出す。

10分ほどかかったが、回線がつかるようになった。日曜日なのにお仕事ありがとうございます。


4年前は、BIGLOBE は切り替え時に、サービスセンターに電話をする必要があった。

といっても、会員番号を告げ、「MNP 切り替えお願いします」と伝えるだけのもの。


これが WEB から申し込めるようになったのはとても楽。



データ SIM は、僕が先日まで使っていた P10 端末に入れる。

こちらは、すぐ通信できる状態だった。


この日はこれで終わり。




月曜日は仕事が忙しく、昨日火曜日に、子供向けに端末を整えた。



P10 をリセットし、長男のアカウントでセットアップしなおす。

Google のバックアップから復帰、を選んだら、ほぼ必要な状態が復元された。


その後、長男が使っていた Honor6 を見ながら、ポチポチとほぼ同じ使い勝手になるように整える。

P10 には指紋認証があるので、使うことにした。長男に指紋押捺させる。


長男が今まで使っていた Honor6 は、ロックをかけていなかった。

当初は「子供みんなが使える端末」として用意したので、誰でもアクセスできるようにややこしい手続きを排除していたのだ。

また、家族との LINE 以外、ほぼ何もできない端末だったので、悪用される心配がないだろいうというのもあった。


しかし、今後は「長男の端末」だ。メールなどを使うこともあるだろう。

セキュリティはしっかりしたほうがいい。


まぁ、データ専用 SIM なので電話はできないのだけど。

(LINE での音声通話は可能)




さて、今までは BIGLOBE 1Gbyte/月 が 1400円。DMM 1Gbyte/月 が 1260円だった。両方音声 SIM。

合計で 2660円。


これを、BIGLOBE 3Gbyte/月に変えると、1500円。

通信容量シェアの SIM が、音声は月額 900円、データは 200円。

合計で、2600円。


月額料金が安くなったのに、データ SIM が一枚追加された形だ。

通信容量はシェアするようになったが、1枚当たり 1Gbyte 使ってもよい、というのは変わらない。


(今までも 1Gbyte 使い切ったことはないので、誰かが多少使いすぎても問題は出ない)




もっとも、MNP 転出、新規 SIM カード発行の手数料などはかかっている。

乗り換えで得をするのには、2年は使わないとならない計算。


(新規発行する子供の分は考えないとして、

 MNP 転出手数料 3000円、SIM カード追加手数料 3000円、準備料 394円。


 音声追加 SIM は月額 900円だけど、プラン変更で +100円かかるので、月額1000円上がる。

 これに対し、DMM は 1260円だったので、月額 260円しか得にならない。


 6394円を260円/月で割ると、24.6 月。2年間使わないと元が取れないことになる。

 まぁ、「子供回線の確保」という目的もあるので、単純に金額だけの問題ではないのだけど)



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

家族

別年同日の日記

09年 テレビゲーム

11年 ピューロランド

14年 日本がメートル条約に加入した日(1885)

18年 イグニス納車

18年 イグニス練習


申し訳ありませんが、現在意見投稿をできない状態にしています

メールの1行が78文字の理由  2019-10-23 17:37:26  コンピュータ

▲目次へ ⇒この記事のURL

先日、Twitter で僕のページを引用してくださった人がいた。


#たびたび書くけど、エゴサーチしてますよ。



引用されていたのは、「OS の登場」のページ。


…書いたのずいぶん前で、内容が拙くて恥ずかしい。

しかしまぁ、大きく間違ったことも書いてないのでそのまま残してある。


で、引用してくださった方は、「1行が80文字」の理由を探していたようだ。


該当ページには、IBM パンチカードが1枚に 80 文字を収めることができたため、コンピューターにディスプレイが付けられた際にも、1行に 80 文字を表示できる必要があった、ということを書いてある。



この話、のちに別のところで詳細解説している。

ハーマン・ホレリス 命日の記事。


ホレリスは、IBM の前身の1つとなる「タビュレーティング・マシン」社を興した人物。

パンチカード集計機を発明し、80桁の数値を記述できるパンチカードを標準化した。


のちに、数値だけでなく文字も表現できるようになったが、80桁、という枠組みは変わらなかった。




さて、冒頭に書いた引用してくださった方は、これが1行 80 文字の理由、としたうえで、「メールの1行を 80文字に制限するマナーは迷信だった」と結論付けていた。


いや、それは論理が飛躍しすぎている。


おそらくは、「古くは」画面の横幅が 80 文字だったことを知り、「今は」その制限がないのだから迷信、という思考の流れだと思う。


しかし、残念ながら 80文字…より厳密にいえば、78文字というのはマナーなどではなくて、システム的な「要求」なのだ。


メールの1行は、78文字を超えるべきではない。


「べきではない」と書かれているように、超えても普通は大丈夫。

だから、緩い制限の「マナー」だと思われがちなのだけど、技術文章で規定された制限なのだ。




インターネットを流れるデータの規定といえば、RFC 。


インターネットメールは、RFC 822 から始まるが、紆余曲折あり、RFC 2822 になり、現在は RFC 5322 となっている。

(なんとなく、822 から連想されやすい番号を割り振っているところが素晴らしい)



で、現在の仕様である 5322 の 2.1.1 節に、こう書いてある。


2.1.1. Line Length Limits

There are two limits that this specification places on the number of characters in a line. Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 characters, excluding the CRLF.

(以下略)


意訳:

2.1.1. 行の長さ制限

1行の文字数には、2つの制限がある。

CRLF を除く1行の文字数は、998文字を超えてはならず、78文字を超えるべきではない。


意訳の中の CRLF というのは、改行を意味する文字のこと。

画面上に表示はされないが、コンピューターのプログラム的には、「1行」の最後には、「行の終わり」を意味する文字が必要となる。


説明すると長いので省略するが、行の終わりは2つの見えない文字で成り立っていて、CR と LF だ。


1行は「改行を除いて」78文字を超えるべきではない。

言い換えれば、「改行を入れて」80文字までだ。



ここに、パンチカードは1枚 80文字という制限が復活している。


パンチカードが 80文字だったために、FORTRAN 言語では1行を 80文字以内と定義しており、ディスプレイは1行に 80文字を表示できるように作られ、初期のスクリーンエディタは1行を 80文字以内としていた。


エディタが1行を 80文字で扱うということは、テキストファイルも1行が 80文字を超えることはない、ということだ。

これを前提として、非常に古いメールシステムの中には、1行を 80文字としてプログラムされたものがあるらしいのだ。


今更そんなシステムが生き残っているとは思えないが、もしそうしたシステムがメールを受け取ってしまうと、80文字を超える部分は削除されたり、強制的に次の行に送られたりする。


RFC ではそうしたシステムを考慮して「78文字を超えるべきではない」としている。


場合によっては一部の情報が削除され、相手に届かなくなってしまう。

それを避けるための制限は、トラブルを未然に防ぐために使用者が心がけなくてはならないもので、マナーや迷信ではない。




ところで、RFC 5322 には、使用できる文字コードの制限もある。



2.3. Body

The body of a message is simply lines of US-ASCII characters.

(以下略)


意訳:

2.3. 本文

メッセージ本文は、単純に US-ASCII で作られた複数行となる。


そう、US-ASCII しか使ってはいけないのだ。

英語は許されるが、ドイツ語もフランス語もだめだし、日本語なんて論外だ。


しかし、実際にこれらの言語でもメールは送れる。


どうなっているかというと、US-ASCII 「以外」のメールは、計算によって US-ASCII の文字に「変換」されて送られるのだ。


この計算方法のひとつに、MIME がある。


US-ASCII に変換されるといっても、日本語が英語に翻訳されたりするわけではない。

単に、日本語の文字を示す「数値」を計算して、数文字の US-ASCII の組み合わせで表現されるだけだ。


変換の際、結果として得られる US-ASCII 文字列は、76文字ごとに改行を入れる、という決まりとなっている。

この結果、元文章の1行が 80文字以上になっていたとしても、通信経路上ではちゃんと 80文字以内に収まっている。


結果的に、「80文字を超えるべきではない」という技術的制限は守られているのだが、利用者がそれを気にする必要はない。




…と、これだけなら「80文字制限は迷信」という最初の話でも、まぁいいかな、ってことになるのだけど、話はもう少し続く。



RFC 5322 で書かれているのは、メールの内容の扱いであり、「MIME の扱いは別議論」としている。

つまり、いったん MIME に変換された際には 80 文字の制限が守られるとしても、それは「メールが」 80文字の制限を守っているのとは違う扱いになる。


通信経路上の問題が解消したとしても、メール自体の問題は残っているのだ。




また、上に、US-ASCII に変換する「計算方法の一つに MIME がある」と書いた。


別の方法もあって、その方法を使うと、MIME の「1行 76文字への変換」が行われない。

この場合、通信経路上の問題も解決していないことになる。



MIME は比較的新しい方法で、日本語の場合、古くは JIS コードでメールの通信が行われた。

これも、「日本語を US-ASCII に変換する計算方法」の一つだ。


そして、今でも互換性のためにこの方法を使えるメールソフトは、結構多い。



JIS コードが当たり前だった当時、よく言われたマナーとしては「1行は 36文字以内」だった。


JIS コードでは、日本語1文字は、英語2文字で表現される。

だとすれば、78文字の制限は、39文字以内となるはずだ。


残る3文字はどこに行ったのだろう?


実のところ、JIS では、ASCII と JIS を切り替えるために、ASCII に規定された「ESC」を使用した。

ESC とは、ASCII から「脱出」して、独自の文字コードを使うために設けられた規定だ。


そして、JIS コードは、ESC に続いて2文字を送ることで、日本語と ASCII を切り替える。


行の頭で日本語を開始し、行の終わりで日本語を終わるとしたら、これに 6文字が必要になる。

日本語に変換すると、3文字分だ。


つまり、これが日本語にした際に消えた3文字分だ。

JIS コードを使用する場合、日本語で RFC の規定を守ろうとすると、1行が36文字以内でないといけない。




ちなみに、行の中に ASCII を入れたりすると、そのたびに切り替えコードが入るため、書いてよい文字数はそれだけ減ることになる。


…JIS でメール書いていた時代でも、80文字を超えて問題出るような環境はまずなかったから、そこまで気にしなかったけどね。


#現在、JIS コードには iso-2022-jp という名前が与えられている。

 JIS コードは、日本国内のローカル規格、iso-2022-jp は国際規格だ。




メールに限らず、通信手段というのは、「相手」や「通信経路」など、多くの参加者があって成立するものだ。

そして、多く参加者があるということは、そのどこに問題が潜むかわからない。


RFC がいまだに1行を 80文字に制限しているのも、実際に過去に 80文字の制限を持つプログラムがあり、今でも残っている可能性があるからだ。


もっとも、RFC5322 の中には、80文字で情報を切り捨ててしまうような環境が本当にあるとすれば、それ自体が RFC5321 違反だ、と言及している部分もある。

(5322 は「メールの書き方」を規定していて、5321 は「メールの送信方法」を規定している)



MIME を使っている場合は、途中経路の問題は気にする必要はないだろう。

MIME によって行は 76文字に揃えられ、決して 80文字を超えることはない。


しかし、この場合も、相手が 80文字を超える行を扱えるとは限らない、ということに注意だ。


…まぁ、そんな古いメーラーを使っている場合、MIME で変換された本文を、元に戻すこともできないような気がする。

もし戻せたとしても、UTF-8 が表示できない、なんてことになりそう。


あまり気にしすぎる必要はないけど、ちょっと気に留めとけ、くらいの問題か。




RFC って、「自分には厳しく、他者には寛容に」という精神なんだよね。


超えるべきではない、と言われているのであれば、自分は超えないようにしないとならない。

でも、誰かが超えてしまったとしても、違反だと怒るのではなく、何の問題もなかったかのように扱えないといけない。


RFC の「規定」って、そういうものなの。


だから、80文字を「超えるべきではない」と規定されているのであれば、少なくとも自分は超えないようにした方がいい。

超えたとしても、「寛容」の精神で、おそらく何も問題は出ないのだけど。



ここで、問題が出ないからこそ、ただの「マナー」だと言われてしまいやすい。

でも、問題が出なくても違反行為で、「寛容さによって」助けられただけという意識は必要。



2019.10.29 追記


そもそも、なぜ「US-ASCIIしか送れない」なんてことになっているのか、という疑問をいただきました。


簡単に言うと、今のコンピューターは 8bit を情報の基本単位としているけど、古いコンピューターには 7bit のものがあるから。

US-ASCII は、7bit で文字を表現するようになっています。



この話、詳細はちょうど10年ほど前に書いてます。

少し内容が古い(最新 OS が Windows 7 だったり、メールの JIS 送信がまだ普通だったりする)けど、以下にリンクしておきます。


「その文字」はインターネットで使ってはいけないのか?




▲目次へ ⇒この記事のURL

別年同日の日記

03年 当たりました

15年 古くて非力なマシンをLinuxBeanで再生してみた

15年 マイケル・クライトン 誕生日(1942)

17年 P10 に乗り換え


申し訳ありませんが、現在意見投稿をできない状態にしています

イベント終わりました  2019-11-17 15:45:02  コンピュータ

▲目次へ ⇒この記事のURL

イベント終わりました

先日書いた日記の続き。

しばらく日記書いてなかったもので、リハビリみたいなもので、どうでもいい身辺雑記書いてます。




現在一緒に仕事をしている会社、別に名前とか出してもよいとは言われているのだけど、この日記上では名前出していない。

その仕事先の名前(商品名でもある)で検索されて、中の人だとわかるのもなんとなく嫌なので。

(僕はその会社の手伝いをしているが、社員ではない。そんな人の話が会社の意見だと思われても困る)



でも、前回リンクした記事を読めば、何の仕事かはすぐわかる。

「このページを読んだ人が知っていてもいいが、商品情報を頼りにしてここに来ないで欲しい」ということだな。




で、土曜日の夜に、東京ビッグサイト…の「壁」に、映像作品を投影するコンテストが行われた。

いわゆるプロジェクションマッピングというやつです。


応募資格は学生だったのかな。

大学生や専門学校生。プロの映像作家はダメだけど、映像の専門校生はいい。



本番は土曜日だったのだけど、金曜日の通しリハーサルに立ち会った。

一応、本番終わるまではリハーサルの話とか書いちゃまずいだろ…と思っていたので、日記に書くのは本番が済んだ今日になった。




このコンテストでは、最終審査は審査員がやったのだけど、「一般審査」として、見た人は誰でも作品の点数をつけられた。

最終的に、平均点が高いところには「観客賞」が贈られる。


(結果、審査員が付けた「最優秀賞」と、「観客賞」は同じチームだったようだ。

 僕は本番ではなくリハーサルで見ただけだけど、このチームは群を抜いて出来が良かった。納得の結果だ。)



一般審査の投票システムとして、一緒に仕事をしている会社のシステムが使われた。

ビッグサイトの壁面に QR コードを表示し、そこから誘導される WEB ページで「投票」すると、リアルタイムに点数が集計されるのだ。


壁面は非常に大きいし、見た人は誰でも投票できる。会場の広場で見ている人は当然、数百メートル離れたところの人だって参加可能だ。

そういう「ゆるい」審査なのだけど、そうした集計ができるシステムは、案外少ないのだ。



そして、集計結果は…点数は、リアルタイムには表示しない。それは、最終結果の発表までのお楽しみ。

その代わり、映像について感じたことを「すごい」「楽しい」「かっこいい」の三択で選んでもらっているので、その割合を表示する。


円グラフがリアルタイムに動いているものが、ビッグサイトの壁に表示される、というだけなのだけど、この部分のシステムを僕が担当しました。


これがね…前日リハーサルまで、実際の映像が見えないので、想像で作るしかなかったの。

文字が大きくないとつぶれちゃうんじゃないか、コントラストが強くないと見えないんじゃないか…って、想像で作り上げるしかない。


直前の日記に「必要なら現地で最終調整」と書いていたのはそのため。



表示してみたら、十分にきれいで何も調整は必要ありませんでした。




一応、円グラフを動かす部分は普段から使っていたプログラム。

でも、普段は円グラフの横に「凡例表」があり、そこにアンケートの内容などが書いてあった。


(グラフの領域には、1 2 3 という数字だけがあり、横に対応表があるわけです)



でも、今回はビッグサイトの三角形の外壁に表示したので、凡例表を出すことはできなかった。

グラフ内に直接文字を入れてほしい、と言われていました。


最初の段階から、「グラフが細くなると、文字重なっちゃうと思うよ?」と言っていたのですが、実際作ってみたら予想以上に深刻でした。


先に書いたように、プロジェクションだと細かな部分がつぶれやすいので、文字をできるだけ大きくしないといけない。

当然大きい方が重なりやすいわけだけど、その状態でも「割合を示す % 部分は読めるようにしたい」という要望がありました。



もう、事前に試行錯誤の連続。幸いなのは、選択肢が3つしかなかったこと。


選択肢が3つだから、「細い領域の両隣のうち、少なくとも一方は表示面積に余裕がある」と確定しています。


そこで、表示面積が細い場合(具体的には、角度にして60度以下になった場合)は、両隣のうち、より広い方にはみ出して文字を表示してもよいことにしました。


(具体的なアルゴリズムとしては、文字は表示領域の中央に出すのだが、60度以下の場合は、広い方にはみ出して60度あるものとした中心に表示を行う)


ただ、両側とも十分に広いばあには、今度逆に「片側に文字が寄る」表示は不自然。

そこで、こうした場合は広い方に寄せる処理をしない、とか、いくつかの場合分けを行います。



これでもまだ、1つの領域が 80% とかとってしまうような極端な状況では、文字同士がぶつかることがありました。


そこで、20% 以下になった場合には、文字サイズが小さくなっていくようにします。

20% 以上なら 100% の文字サイズで、10% 以下なら 80% 。間は滑らかにつなぎます。



これで、問題のないグラフ表示になりました。




この表示、評判良かったので今後も使えるようにしたい…と、仕事先の社長から言われてます。

でも、それなら3つ以上の選択肢でも使えるようにしないと。


今は、文字の表示中心が、円グラフの中心から等距離のところにあるのだけど、本当はこれも可変にしたい。

グラフ中央から「近い」「遠い」をうまく組み合わせれば、もっと文字を表示しても読めるはず。


ただ、そうなってくると文字同士の当たり判定を入れたいのだよね。

今のグラフ表示基礎ルーチンは僕が作ったものではなく、そこまで複雑なことができる作りになっていない。


もっというと、データが決まっていて「うまく表示する」目的なら、内部的に試行錯誤して最適配置を求められるのだけど、リアルタイムに移り変わるのを違和感なく表示するのは至難の業。


まぁ、そこがゲーム的で面白そうなチャレンジだと思ってる。

(試行錯誤させてもらう時間があればね)


▲目次へ ⇒この記事のURL

別年同日の日記

02年 友人宅へ

11年 バックアップとデフラグ

13年 1週間の記録

15年 ハーマン・ホレリス 命日(1929)

15年 ハムスター死去


申し訳ありませんが、現在意見投稿をできない状態にしています

遊びプログラム  2019-11-19 17:49:06  コンピュータ

▲目次へ ⇒この記事のURL

今日は一日仕事があいてしまったので、遊びプログラム。

まだ完成していないし、明日からは普通に仕事に戻るので、完成するかもわからない。




Twitter をエゴサーチしているが、ファミコンの画面についてのページを引用してくださった人がいた。


ファミコンでは 52色表示可能、という、表示できる色の一覧だな。


どうやら、その人は「ファミコンの表示」に興味があり、適当な画像をそれっぽくするフィルタを作っていたらしい。


Twitter のログを追って分かったことには、最初は「適当な54色」に減色してみたものの、どうも「それっぽい」画面にならないので、情報を探して僕のページを見つけたようだった。


どうも、当初は RGB 空間を適当に区切って 54色にしたようだ。

しかし、どこかで「RGB ではなく、NTSC の Y/C 空間で考えないといけないようだ」と、情報を探して僕のページに辿り着く。


そして、そこで


・既定の 52色

・16ドット以内で使えるのは、背景色含めて4色だけ

・その4色の組み合わせは、全画面内で4セットだけ


という厳しい条件を知り、「なんだかわからない」とツイートして終わっている。




さて、僕も以前から、ファミコン風画面フィルタは作ってみたかった。

ちょうどよい機会だから、「厳密にはしない」つもりで作ってみる。


とりあえず、52色減色から。

RGB を HSV に変換してからファミコンパレットに適用してみようと思ったのだけど、難しい。

H 信号を参考にして、「パレットの近いあたり」までは見つけられるとわかったので、その周辺を総当たりで「近い色」を探すようにしてみる。


とりあえず、ファミコン 52色への減色はこれでできた。

ディザをかけたりしないので、最適な画像変換ではないけれど。



つぎに、52色自由に使ってはならない、という制限をかけてみる。

使われる色を集計し、上位 12色しか使ってはならない、としてみたら、まだまだ綺麗な絵が出る。


では、6色まで落としてみよう。

というのも、グラディウス2のデモ画面で、ビッグバイパーの絵が6色で書かれているからだ。


…いい具合に「色合いが不自由」な感じが出て、ファミコンらしくなった。




つづいて、「16ドット以内に4色」という制限を作ってみる。

4色のうち1色は「背景色」なので、一番使われている色を背景色にすることにして、それ以外の色で 16ドット以内で使用頻度を集計する。

これで、上位3色+背景色で描けば、それらしくなる。


…案外、きれいな絵が出てしまう。

いろんな絵で試すと、多少不自然なところも現れるが、この条件だけではまだ「ファミコンらしさ」が出ないようだ。


やっぱり、「全画面で3色セットを4つまで」の制限も入れないといけないだろうか。




ファミコン画面は 256x224 (縦方向は VRAM は 240 ドット分あるが、表示は 224ドット程度とすることが多い)として、16x16 ドットのタイルで区切ると、16x14 タイルになる。


それぞれを、背景色を除いた3色に減色したうえで、同じ色の組み合わせになった数を集計する。

そして、使われた数が「少ない」パレットを、使われた数の「多い」パレットに吸収する。


吸収する際は、3色のうち少なくとも2色が同じパレットに吸収することにした。

この際、使用された数もちゃんと吸収させる。


できる限り吸収を繰り返したうえで、改めて集計された使用数の順に並べ治す。

最終的に、上から4つのパレットを採用する。



そして、このパレットを使って画面を描くと…うん。いい感じに四角く色が化ける。

ファミコン時代にはよくあったよね。無理やり感のある絵。




しかし、四角い不自然さはあっても、まだファミコンにしてはきれいすぎるのだ。

それは、画面全体で、色以外は自由に絵を描けてしまっているから。


ファミコンは、8x8 ドットのキャラクターを並べて絵を作る。

このキャラクターは 256種類しか定義できないのに、画面全体は 896マスある。


だから、自由に絵を描くことはできないのだ。

色だけをファミコン風に変換しても、キャラクターの不自由さで違和感がある。



本当は、「似た部品」を探し出して、無理やり共通化することで不自然さを出していけばよいのだけど、そこまでやるのは結構面倒だ。


そこで、せめて「四角い塗りつぶし」を増やすことにする。

8x8 ドットの範囲内、64ドットのうち、52ドット以上同じ色だった場合には、思い切って 8x8 を塗りつぶしてしまう。


52ドットに根拠はない。色々試して、それくらいがなんとなくいい感じだった、というだけだ。

塗りつぶし部分は、絵としては「使いまわし」になるので、絵が自由に描けない不自由な雰囲気が出る。



とはいっても、これでも絵がある部分が 256マスには収まらないのだけど…

かなり塗りつぶしが多い絵でも、256以上のキャラクタを定義したことになってしまう。




まぁ、遊びプログラムなので、本日はここまで。


あまり満足いく結果が得られていないので、公開するにはまだ早いかな…



▲目次へ ⇒この記事のURL

別年同日の日記

01年 11/18

02年 また風邪?

04年 地鎮祭

08年 エジソンロック

18年 なにもしてないのにこわれました


申し訳ありませんが、現在意見投稿をできない状態にしています

久しぶりのperl  2019-11-20 17:03:07  コンピュータ

▲目次へ ⇒この記事のURL

久しぶりに仕事で perl を使った。


現在仕事を受けている会社で、サーバートラブルがあった。

そこで、トラブルに遭遇したユーザーを特定したいという。


ここでのサーバートラブルは、「サーバーに接続できなかった」というトラブルだ。

そのため、サーバーには接続できなかった人を特定するログは残っていない。


しかし、リバースプロクシを入れてあったため、プロクシにはログが残っている。

ただ、このログは通常の WEB アクセスのログであり、ユーザーを特定できる情報が残っていない。



実は、問題のあったアクセスは POST アクセスなのだ。

そして、POST の body データとしてユーザーを特定できる情報が入っている。

body として送られるデータは一般的に大きいため、普通はログに残すような設定にしない。


つまりは、問題のある URL にアクセスした個人を特定したいのだが、その個人を特定する情報は記録されていない。



いや、まだ手はある。

知りたい URL アクセスには個人特定情報は入っていないが、その前に必ずアクセスする URL は GET アクセスで、この時は URL パラメータとして個人を特定できる情報があるのだ。


そして、これは「直前の URL」なので、おそらくは問題となる URL のアクセスの際にも、IPアドレスは変わっていないだろう。


ただ、IP アドレスは使いまわされる可能性がある。

IPアドレスだけで「同じユーザーのアクセス」と認定するのは危険で、user agent 情報も一緒に使うのが良いだろう。




まとめると、つまりこういうことだ。


・特定 URL にアクセスして、接続できなかった (status が 302だった)個人を特定したい。

・特定 URL アクセスには個人特定の情報はないので、直前の別 URL アクセスの際の情報を使用したい。

・2つの URL の間が「同じユーザー」であることは、IP アドレスと user agent の一致で確認。


さて、これを2万行ほどあるログに対して、処理したい。

トラブルの事後処理なので、できるだけ早急に。



あぁ、これは perl の出番だな、と瞬時に判断したが、perl 使うの久しぶり。

大丈夫だろうか、と思いながらスクリプトを書き始める。


結論から言えば、うっかりミスはあったが過去のノウハウは活きた。




WEB サーバーのログは、基本的にスペース区切りなので、情報を得たいときはスペースで分割する。

…という風に、処理慣れしていないプログラマなら思うだろう。


perl では、1行にスペース区切りで複数のデータが入っているときは、


split;


というたった一命令で分割処理が終了する。

以前、perl の命令は暗黙のデフォルトが多いという話を書いた。


本当は、split 命令は、「分割したいデータ」と「分割する文字」を与え、「分割した内容を受け取る変数」に代入を行う必要がある。


しかし、全部省略すると、$_ (通常は、現在注目している行)を連続したホワイトスペースで分割して、@_ (一時的な配列)に入れてくれる。とても便利。


なので、WEB サーバのログでも、split で分割したくなってしまうのだ。



でも、WEB サーバーのログの中には、「スペースが許容されている情報」が収められている。

サーバーにどのようなアクセスがあったか、という情報と、user agent は、内部にスペースが入るのだ。


そのため、スペースで区切ると、情報の途中で区切られてしまうし、分割後の「情報」の位置が安定しないしで、処理しづらいことこの上ない。



もちろん、ログ内で混乱が起きない工夫はあって、スペースを含む情報は " (ダブルクオート)で括られることになっている。

だから、ダブルクオートを見つけたらその内部をひと固まりとして処理するようなプログラムを書けば…



というのは、正攻法だけどひたすら面倒くさくて時間のかかる道。


発想を変えよう。最初に、" で区切ってしまえばいい。


アクセス情報と、user agent は " で括られているのだから、この段階で適切な位置にある情報が取得できる。


IP アドレスやアクセス時刻は、" で括られない情報なので、上記処理で手に入った断片を、さらにスペースで区切る。


これで、各種情報が手に入る。


過去に何度も WEB サーバーのログを処理していたので、こういう処理ノウハウはすぐに思い出した。




さて、まずは、「直前の GET アクセス」から個人を特定できる情報を拾い出そう。


これは、特定の URL を条件として、正規表現で拾い出してやれば終わりだ。

IP アドレス、user agent もすでに取得してあるので、この2つの組をキーとした連想配列に、個人特定情報を保存しておく。



つづいて、情報が欲しい「特定 URL にアクセスしたとき」の処理も作る。

この URL も、正規表現で拾い出せばよい。


ただ、この「特定 URL」は、一つではない。

末尾部分がサービスの違いを示す数値になっていて、一人のユーザーが複数の「数値の違う」URL にアクセスしている可能性もある。


そのため、URL の末尾に入る数値も一緒に記録してほしい、とのリクエストだった。

これは、正規表現の ( ) (グルーピング演算子)で取り出す。


ここでの正規表現は「データを得るためのもの」ではなく、if 文の実行条件を示す「比較」にすぎない。

しかし、「比較」でデータを取り出せてしまう、というのも perl の便利な部分だ。


条件はもう一つあった。この、特定 URL のアクセスが「302 エラーになった時」だ。

これも、ログにはステータスが入っているので、302 の時を条件に入れればよいだけ。



さて、無事条件に合うアクセスがあったら、時刻と URL 内部の数値と、個人特定できる情報を1行にまとめて出力してほしい、というリクエストだった。


個人特定情報は、先に書いたように、IP アドレスと user agent に紐づいた形で保存してある。

これを使えばいい。


時刻は、サーバーログに入っている形式と、求められている形式が少し違ったので、変換する。


ログに入っているのは [20/Nov/2019:15:30:28 +0900] という形式。

必要なのは、2019-11-20 15:30:28 という形式。


これも、正規表現でグルーピングを使えば必要な情報が得られるので、整形して出力するだけ。




出力は、2通り用意してほしいと頼まれていた。

まずは、エラーが出たすべてのアクセス。


もう一つは、エラーが出たことで繰り返しアクセスする人も多かったので、「同じ URL への同じ人のアクセスは、初回のみを記録して後は省略」したもの。


まずは、エラーが出たすべてのアクセスを出力し、ファイルに残す。

続いて、プログラムに少し追加。


URL と個人特定情報を組として、一度出力したら「1」を記録するようにした。

この記録があったら出力済み。事前に確認し、出力処理を飛ばすようにした。


これで出力した情報もファイル化する。




さて、ここまで整形した情報を得るまで、1時間程度。

久しぶりの perl としては、まずまずだろう。


しかし、データを送信してしばらくたって、先方から「おかしい可能性」を指摘される。


どうも、「同じ URL への同じ人のアクセス」を省略したほうのデータが、少なすぎるように思うというのだ。



しばらくプログラムを見てみるが、すぐに原因が特定できない。

「すべて」を出力したファイルに対し、unix コマンドの sort と uniq を駆使して「同じ URL への同じ人のアクセス」を省略したファイルを作ってみる。


明らかに数が違う。データ件数で、15 倍くらいの情報があった。



これ、連想配列のアクセス方法を間違えているためだった。


最近使っている、Javascript でも PHP でも、連想配列アクセスには [ ] を使う。

でも、perl は連想配列は { } だった。


完全に自分の頭から抜け落ちていた「常識」に気づくまで、1時間くらい。

これに気づいて修正したら、出力データ件数が増えた。


出力データを wc してみる。行数や語数を数える unix コマンドだ。


「すべてのデータ」出力は、改良前と後で同じ件数だが、出力データサイズが微妙に違う。


改良前と後のファイルを diff して違いを探す。

どうやら、件数は同じでも、個人特定情報の部分が違う。


改めてプログラムを見て、連想配列アクセスを間違えていたため、個人情報の紐づけが正しくなかった、と判明。

なので、先に作った全件データは誤り。新しい方が正しい。



この正しいデータをもとに、sort | uniq したデータと、プログラムで「同じ URL への同じ人のアクセス」を省略したファイルは、同じ件数・同じ出力サイズだった。


sort した関係で順番などが異なっているのだけど、別の方法で集計しても、プログラムの集計と同様になったことが確認されたので、このデータは正しいと判断。



ここまで、最初の依頼から2時間半ほど。

データを送って確認してもらい、おそらく正しいだろうという判断になった。



#そもそも、確実に正しいか確かめる方法はない。

 正しいデータがないから、こんなプログラムをしているのだもの。




…と、今日記を書いていて、ここで終わろうと思ったところ、ちょうどバグ報告が来た。

出力の中に、「個人特定情報」が入っていない行がある、とのことだった。


元になるアクセスログを開き、「報告すべきエラー行」を特定する。

それから、そのエラー報告に含めるための、「個人特定情報」を拾い出せる、事前の行を探し出す。



…ここで、ミスをした。

というのも、「個人情報」は当然ないので、バグ出力に含まれる情報で行を探したが、実は該当行が2行あったのだ。

しかし、僕は「時系列で上にあった行」だけを見つけて、その行を元に周囲を調べ始めてしまった。


どう考えてもデータはおかしくないので、自分のプログラムのミスだろうと探すこと30分以上。


いろいろ確認してもおかしくないので、データに戻り、再度おかしいところを探す。


この作業中、やっと自分の過ちに気づく。


そして、2行目の該当行を元に、同じ IP アドレスでアクセスしている「事前の」行を調べると、存在しなかった。

事前アクセスがないので、「事前のアクセスから」情報を引っ張ってくることはできない。

プログラムには問題はなく、データの問題だった。



ここまで確認して、報告。

ついでに、事前データはないものの、「事後の」アクセスから個人を特定できたので、その情報も報告。


ひとまず作業終了となった。




昨日日記に書いた「遊びの」プログラムもそうなのだけど、こうしたパズル的なプログラム作業は、やっていて楽しい。

保守性とか読みやすさとか考えないで、ただ動くプログラムを書けばいいからね。


仕事なので時間制限もあったりするのだけど、それも踏まえて「最短時間で解決するにはどうすればいいか」というような段取りから考えるのが楽しいのだ。





▲目次へ ⇒この記事のURL

別年同日の日記

01年 11/19

02年 80歳で歯を20本残そう

04年 最後の親不知

06年 絵本

13年 任天堂の会社設立日(1947)


申し訳ありませんが、現在意見投稿をできない状態にしています

mysql で varchar を int に alter table する。  2020-01-16 20:00:56  コンピュータ

▲目次へ ⇒この記事のURL

興味ない人には、なんのこっちゃわからないタイトル。


仕事で複数人数、複数のマシンで開発を行っているので、それらのマシンを同期しないといけない。

プログラムなんかは github 使って管理しているのだけど、DB 構造なんかの問題もある。


で、mysql (実際には mariadb だけど)のテーブル構造を、ファイル化してある。

このファイルは github で管理し、新しいサーバーを建てるときには、ファイルを mysql コマンドで

流し込めば完了する。


そして、開発中に「変更」になったものについては、alter table を列記したファイルを作る。

github から最新のデータを得たときなどは、このファイルを mysql に流し込めば完了する。


…というつもりで作業していたら、そう単純じゃない問題があったよ、という話。




もともと技術者でないとわからない話なので、ついてこれる人だけ読み進めてほしい。


alter table でテーブル構造の変更はできるが、alter table には IF NOT EXISTS というオプションがある。

「もし、その構造が存在していないなら」新しく追加する、などという動作を行う。


だから、先に書いたように、プログラム更新のたびに、必ずこの「 DB 構造差分データ」を DB に流し込めば、構造がすでにあれば無視され、なければ正しく追加される。



でも、「varchar(4) を tinyint に変えたい」で詰まったんだ。


設計段階ではいろいろあって varchar(4) してあったけど、事実上小さな数値しか入らない、と分かったため。



直接 alter table で変換しようとすると、「文字列を数値に変えられない」とエラーが出て失敗する。

これは、何もデータがない時に、NULL 文字列が入っていたため。


数値になった際も、0 は使わないとわかっている。だから、NULL 文字列は 0 に変換してほしい。


というわけで、事前に



UPDATE [table] SET [col]='0' where [col]=''


という感じで、'' を 0 に変える。それから alter table すればうまくいく。



…というわけでもなかった。




上の UPDATE 文、[col] が varchar の時は動いた。

でも、tinyint になると、エラーになって止まる。


先に書いた通り、このファイルはプログラム更新のたびに読み込まれるのだ。

すでに tinyint の時には、何もせずにスルーしてほしい。


エラーの理由はわかっている。


[col]は数値なので、where 句に書かれた比較は数値で行おうとする。

しかし、NULL 文字列は数値ではないので、「文字列を数値に変えられない」とエラーが出て失敗する。


…最初の問題に戻ってきた。

んぎぎぎぎ…どうすればよいのだ。


仕方がない。IF 文を使ってみよう。

僕は mysql を「単に使っていた」歴は長いのだけど、php や javascript と組み合わせていたことが多いため、sql のみで記述するファイルとして、IF を使ったことがない。


やりたいのは、「[col] の型が varchar の時だけ、各種処理を行う」だ。


[col]の型を調べるには、



show columns [table] like '[col]'


とすればよい。これで、画面上に型が表示される。


…いやいや、それはダメだ。画面上に出ただけでは、IF 文で判断できないじゃないか。

しかし、どうすればこれを基に IF の判断につなげられるのかわからない。




ところで、mysql はデータベースだ。データの扱いに長けている。

どれくらい長けているかというと、「自ら作成するデータベースの構造も、データベースとして格納されている」のだ。


つまり、先ほど show columns で見た内容も、実はデータベースに入っている。

データベース名 INFORMAION_SCHEMA の中に、テーブル名を示すテーブルや、カラム名を示すテーブルがある。



SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name=[table]' AND column_name='[col]'


とすれば、目的のカラムのデータ型を得られる。


…が、これもまだ、表示されるだけだ。


また、サーバー内に複数のデータベースが入っており、同じテーブル・カラムがそれぞれにある場合、全てが表示されてしまう。

そのためさらに現在接続しているデータベース名で絞り込む必要がある。




「表示しかできない」という問題に対しては、show columns は名前の通り本当に表示だけだが、select は sql の中心的な構造なので、素敵なオプションがある。


先のコマンドの冒頭を



SELECT data_type INTO @type FROM ~


と変えてやる。 INTO @type が挟まっただけだ。

しかし、これで「表示」するのではなく、@type という変数に格納されるようになる。


もう一つ、目的外のデータベースも検索対象になることについては、WHERE の直後を変えてやる。



~ WHERE table_schema=database() AND tabel_name~


これで、データベースを絞り込める。




ここで、@type には varchar か、tinyint が入っているはずだ。

目的は、varchar の時だけ、tinyint に alter table することなので、



IF @type='varchar' THEN
  UPDATE [table] SET [col]='0' WHERE [col]='';
  ALTER TABLE [table] MODIFY [col] tinyint DEFAULT 0 NOT NULL;
END IF;


みたいな感じで処理してやればよい。


ただし、このまま mysql クライアントで流し込むとエラーになる。

; は「mysql サーバー的には」コマンドの区切りなのだが、「mysql クライアント的には」命令の終わりを兼ねるためだ。


DELIMITER で命令の終わりを変えられる。

なので、最初に DELIMITER で // を命令の終わりに変え、全てが終わった後で元の ; に戻してやるといい。


最初の SELECT から含めて全部を書くと、次のような感じになる。



SELECT data_type INTO @type FROM INFORMATION_SCHEMA.COLUMNS
  WHERE table_schema=database() AND table_name=[table]' AND column_name='[col]';
DELIMITER //
IF @type='varchar' THEN
  UPDATE [table] SET [col]='0' WHERE [col]='';
  ALTER TABLE [table] MODIFY [col] tinyint DEFAULT 0 NOT NULL;
END IF;
//
DELIMITER ;




同じことで悩んでいる人、結構多そうだと思うのだけど、探してもそういう記事を見かけなかった。

ただ、「show columns の結果を変数に入れたい」とか、「文字列から数値のキャストの癖が強すぎる」とか、悩んで解決できていない記事は多数見つけた。


それらがすべて、僕と同じ悩みで書かれたわけではないだろう。

でも、同じ悩みの人の解決の手立てになれれば、幸いである。



▲目次へ ⇒この記事のURL

別年同日の日記

04年 タワーリング・インフェルノ

15年 スーパーマリオとパックランドの関係性について


申し訳ありませんが、現在意見投稿をできない状態にしています

MacBook Pro 購入  2020-02-16 10:49:41  コンピュータ

▲目次へ ⇒この記事のURL

仕事のために「しかたなく」MacBook Pro を購入しました。


あまり使う予定がないので、一番安いやつ。それでも、税込みで15万円ほど。

僕が今使っているメインマシンより高いんですけど…




以前は、携帯電話やスマホ向けの WEB ページを作る仕事が多かった。


特定機種で動作がおかしい、という報告があった時も、クライアント側で該当機種を貸してくれて、動作確認して修正、ということが多かった。

だって、機種が多すぎるから、報告があるたびにいちいち買ってられないもの。



しかし、今受けている仕事は、「通常の」WEB サービスだ。

動作保証は、 Windows の IE11 / Edge / FF / Chrome と Macintosh の FF / Chrome / Safari で行わないといけないことになっている。


機種でいえば「2機種」でよい。

そして、さすがに2機種だとクライアントが貸してくれることもなく、自分で買うことになった。



特に重要なのは、Windows で動作確認できない Safari なのだ。




で、さっそく以前から問題になっていた「Mac でのみ起こる表示崩れ」を調べた。

Mac だと Safari だけでなく FF でも起こる、と報告を受けていたので、フォントの問題なのだろうなぁ、とは予想していた。


思った通り、フォントの問題だった。


Safari の開発者機能を使い、CSS の font-family をリアルタイムに書き換えてみる。

そして、表示崩れを起こさないものを確認し、CSS ファイルを書き換える。


これで問題は解消した。


所要時間は 30分ほど。

とりあえず、今回購入した目的は果たした。


これだけのために15万円ですよ・・・

(まぁ、今後も必要だろうから買ったのだけど)



▲目次へ ⇒この記事のURL

関連ページ

iPhone SE 購入【日記 20/08/22】

別年同日の日記

05年 忙しい一週間・水曜日

15年 「ああ播磨灘」ゲームボーイ版

17年 パソコン通信が生まれた日(1978)

18年 Harley-Davidson & L.A. Riders


申し訳ありませんが、現在意見投稿をできない状態にしています

node-tyrant のバグ修正  2020-02-22 15:31:35  コンピュータ

▲目次へ ⇒この記事のURL

今日は、プログラマ向けのちょっとした推理小説。

まぁ、実際に今週体験したことなのだけど。




世の中には多くのデータベースソフトがあるが、SQL とそうでないものに大別される。

そして、「そうでないもの」の中に、key value store と呼ばれる種別のデータベースがある。


ざっくりと違いを書くと、SQL は多機能だが、高速ではない。

key value store は非常に貧弱な機能しかないが、無茶苦茶高速だ。



SQL ってのは多機能なので作るのが大変で、昔は高価なソフトしかなかった。

それが、PostgreSQL と MySQL の台頭で、無料でも使えるようになり、普及した。


ちょうど WEB の黎明と重なり、最初は重宝された。

しかし、WEB が当たり前の社会インフラになると、1秒で何千というページアクセスを支える必要があり、より高速な DB が求められ始めた。


そこに登場したのが key value store だ。


memcached というソフトが最初のきっかけとだったと考えていい。

現在人気があるのは、Redis だと思う。




Tokyo Cabinet は国産の key value store で、10 年くらい前に人気があった。


本当に機能が少なく、ネットワークにも対応していない。

これをネットワーク対応にする後付けのソフトが Tokyo Tyrant だ。


ちなみに「Cabinet」は、書棚などの意味。データを保管する場所だな。

しかし、英語では「内閣」などの意味もある。政治の中枢を担う組織。


そして、Tyrant は「暴君」の意味だ。

Cabinet を意のままに操るもの。面白い名前だと思う。




さて、現在お手伝いしている仕事のプログラムで、Tokyo Tyrant (以下 TT と表記)を使用していた。

以前は PHP で扱っていたらしいのだが、プログラムを完全に作り直していて、Javascript (node.js) ベースになっている。


移植は僕がやったわけではなく、他の方の作業によるもの。

ここで、完全に一から作るのは大変なので、フリーのライブラリを利用したらしい。




…というわけで探してみたら、これだな。

node-tyrant


開発開始から半年以上たつが、特に問題なく使っていた。




先週頭くらいに、僕が新機能を実装していたところ、なぜかサーバー (node.js) が停止する、というバグに見舞われた。


まぁ、自分がプログラムを作っていてバグが出るのだから、自分が悪いのだろうと思って調査を開始する。


プログラムは、とあるきっかけでデータベースのフラグを操作するものだった。

もともと「ボタンを押したとき」に処理をするプログラムが存在したのだ。


しかし、新たに「設定時刻が来たとき」に処理する機能を追加した。


ところが、ボタンを押したときは正常に動作するのに、設定時刻が来たときにエラー停止する。



設定時刻が来た、というのは、cron などの意味ではない。

それでは、せいぜい1分単位の処理で、ユーザー操作とかみ合わない場合があるからだ。


ユーザーが見たときに、設定時刻が来たのであれば、その瞬間に画面に反映されている必要があった。

なので、画面を作るときに、データに記録された時刻を見て、期限を過ぎていたらフラグを操作する。


同じ処理関数を呼んでいるだけなのに、この処理をするとサーバーが停止する。



cron だと、動作するときにユーザー権限が違っていて不具合を起こすようなことがあるが、今回の話はそうではない。ユーザー権限の問題ではない。

じゃぁ、何が問題なのか。問題の切り分け作業に入る。


調査は難航したが、最後に分かったのはこういうことだ。


ボタンを押したときは、ユーザーのアクションを伴うため、フラグが変わった後にページ全体のデータをリロードしていた。

しかし、時刻が来た場合は、サーバー側でフラグ操作するため、必要なデータを書き換えるだけでリロードは起こっていなかった。



そして、「リロードすれば問題ないが、リロードしないと停止する」のだった。




ここで、先に書いた node-tyrant のライブラリだが、さらに改造して使用していた、ということを書いておく。


改造は多岐にわたるが、そのうち一つに「TT からの反応がない場合は、サーバー異常と見なしてサーバーを再起動させる」というものがあった。


サーバー停止は、この機能が働くためだった。

(実際は、停止するとサーバー監視サーバーによって再起動される)


ここで、TT との通信についても触れる必要がある。


TT には、コマンドを送ると、返答が返ってくる。

データはバイナリストリームで、基本的にはデータ長とデータがセットになった chunk 構造だ。


ただし、内部構造はコマンド毎に多少異なる。


バイナリストリームなので、「改行で終了」とかではない。

データ長を信じて処理することになる。




もう一つ、Javascript としての処理の方法を書いておく必要がある。


データはバイナリなので、改行で終了ではないと書いた。

入ってくるデータを常に監視しておく必要があるが、 Javascript では「常に監視」というようなプログラムは書けない。


そこで、EventListenr を使う。何かあったら関数を呼び出して、とシステムに依頼する方法だ。

TT との通信では、「データを受信したら呼び出す」関数を指定しておく。



ところで、ネットワーク越しのシステムなので、リクエストコマンドと返信データの間にはタイムラグが発生する。

そこで、リクエスト時にコマンドをキューに入れておき、データが戻った時はキューを見て処理方法を判断する。

先に書いたがデータ構造はコマンド毎に異なるため、こうしないと処理方法がわからないのだ。



ここで、データが改行区切りなどではない、ということに気をつけないといけない。

Javascript は「何らかの方法で」データが一区切りした、と考えて関数に渡す。


しかし、この区切りが何であるかはよくわからない。

データが途中で切れる、ということはなさそうだが、複数のデータをまとめて受信することはあり得るようだ。




断片的な話が続いて申し訳ないが、必要なことなのでもう少し続ける。


先に「TTからの反応がない時はエラー終了」するようにしてあった、と書いたが、この「反応がない」の定義が重要だ。


上に書いたように、TTへのリクエスト時にキューが積まれ、データが来たときにキューが消費される。

そこで、「最後のリクエストから3秒立ってもキューが解消していないとき」は、TTの反応がなかったとみなされるようになっていた。


TTは高速を売りにするデータベースなので、3秒というのはあり得ないくらい長い時間だ。

そんなに時間が空いたら異常と見なす、というのは、別に悪くないだろう。




さて、「リロードしないとエラー停止」は、この「キューの積み残し」が原因だった。

何らかの原因で、TTが処理できていない、と見なされるのだ。


しかし、エラー停止した直後にDBを確認しても、正しく記録はされていた。

DBからの返事がないだけで、動作はしているのだ。


さらに調べると、返事があるにも関わらずに受け取れていない、と判明した。


この「受け取れていない」は、Javascript が受け取れていないのではなかった。

Javascript が受け取っているにもかかわらず、「プログラムが」取りこぼすのだ。


なぜ取りこぼすのか調べる必要があった。

どんなコマンドを発行して、どんな返事が返ってくるかを調査する。


put コマンド(データの保存を意味する)を送った時、返事が 5byte …「正常終了コード」 1byte と、4byte (32bit) の「0」だとわかった。

これをプログラムが取りこぼす。




プログラムの流れを追いかけると…

先に示したライブラリを、読める人は読んでみるといい。


最終的に、コマンドの結果は 232 行目からの responseMisc で扱っている。

この中で、


if (data.length<9) return [null, -1, null];


という行があった。これは「9バイト未満のデータは扱えないものとして保留させる」指示だ。


5バイトが返ってくるにも関わらず、9バイト未満を認めない。

バグの原因は、どうやらこれらしかった。



しかし、ここで修正を加えるのは早計だ。

こんな単純なバグであれば、「必ず」バグが出て、プログラムがまともに動かないはずなのだ。


にもかかわらず、プログラムは通常動いていて、むしろ停止することの方が少ない。

何かがあるはずだ。



「保留させる」処理の後を考えてみる。

保留は本当に保留で、データを処理しないし、キューも処理しない。

そして、次のデータが来たとき、残っていたデータに「追加」されて、データ処理を再開する。


すると、データが「追記」されたために、データのサイズが増えている。

今度は9バイト以上になっている場合、処理が続行されて、正常な処理になる。



なるほど。普段は問題が出なかった理由が分かった。

先に、「処理の後、データのリロードをしている場合は問題がない」と示したが、追加データがあると処理がうまくいくのだった。




ここまで分かったところで、僕は一旦発注元の会社に報告をした。

自分のプログラムのバグだと思って確認していたが、データベースを扱うプログラムにバグがある。


これは大問題なので、プログラムの作者(古い PHP プログラムを移植した担当者)に連絡が行く。

彼なら TT のハンドリングがわかると思ったからだ。


しかし、彼はライブラリを見つけてきて、目的に合わせて少し改造しただけだという。

すでにある程度ライブラリを調査している僕の方がよほど理解していそうだった。



この時点ですでに僕の仕事は遅れ気味だった。

どうしても取れないバグで悩んでいて、さんざん調査してここまでたどり着いたところだったのだから。



だから、上からの指示は「僕はこの問題を離れ、本来のプログラムの作成に戻ること」だった。

しかし、この問題が解決しないと、プログラムのバグは取れない。


まぁ、「バグは僕のせいではない」ことにして、溜まっている他の個所の作業に取り掛かった。


しかし、他の人の調査報告を横目で見ながら、気になることがあれば手早くできる範囲で調査を続けた。




そもそも9バイト未満のデータを認めない、という処理に妥当性があるのか。


Tokyo Tyrant のプロトコルを調査する。


…少し古いものしか見つからなかった。


ここに、put の返答は処理コード1バイトのみ、と書いてある。

0 なら成功、それ以外ならエラーだ。


しかし、確認するとどうも5バイト返ってきている。

何がどうなっているのか。


プロトコル表あったよー、という返事だけしておく。

TT の現在のバージョンでプロトコルが変化している可能性もある。


うん、きっとそうだ。




別の人が、直接 TT を操作するプログラムを書いてみた。


put コマンドでデータを送り込むと、結果は 1byte が返ってくる、ということだった。


プロトコルのバージョンが違うのでは、という予想は違うことになる。

むしろ、なんで Javascript だと5バイトを受け取るんだ?



再びプロトコル表を見て、気になる。

今まで「返事」のプロトコルばかり気にしていた。put の送信プロトコルは正しいのか?



プロトコル表には、put に対するバイナリコードが書かれている。

プログラム内からこのコードを探す。たしか、先頭付近でバイナリコードの定義が行われていたはず。



// List of Command hex codes for Tyrant var commandCode = { misc: String.fromCharCode(0x90), get: String.fromCharCode(0x30), out: String.fromCharCode(0x20), vsiz: String.fromCharCode(0x38), iterinit: String.fromCharCode(0x50), iternext: String.fromCharCode(0x51), status: String.fromCharCode(0x88), addint: String.fromCharCode(0x60), }


…愕然とした。「put」のコードは、書かれていなかった。



しかし、node-tyrant で put コマンドを呼び出したときに、処理しているプログラムはある。

この処理関数を読んで、やっと気づいた。


node-tyrant のプログラムでは、put コマンドを送るために、put コマンドを使っていない。


TT には misc (それ以外)というコマンドがあり、このコマンドを経由して「隠しコマンド」が呼び出せる


node-tyrant の put は、misc 経由で呼び出される、隠しコマンドとしての put だった。



こうなると、返答データも put と違って当然だ。

プロトコル表に、ちゃんと misc の返答プロトコルが書いてある。


[code:1][rnum:4][{[esiz:4][ebuf:*]}:*]



問題は、この表記方法は作者が定めただけのもので、特に意味は説明されていないことだな。

しかし、コマンド毎に返信データの形式が書かれているので、読んでいるとなんとなく意味が分かる。



[ ] はデータを意味していて、:n はバイト数のようだ。

ここには書かれていないが、省略可能な場合は ( ) で括られる。

複数回繰り返す場合は { } で括られる。



つまり、こういうことだ。


先頭に、処理コード1バイト(0 は成功、それ以外は失敗)

続いて、データ長が4バイト。


さらに、文字列長が4バイト。

文字列が不定バイト。


最後の2行は、セットになっていてデータ長の数だけ続く。



返事を処理する関数での制限、「9バイト」というのは、文字列長までは入っているだろう、という前提のものだったようだ。


後半が ( ) ではないので、省略されることはない、と考えたのだろう。


しかし、{ }:* という書き方が「0回以上の繰り返し」を意味しているようだ。

( ) で括っていないにもかかわらず、0回の場合は消滅する。


つまり、返答データが5バイトの場合がある。


(先に書いたように、間違っていてもなんとなく動くプログラムになっているので、作者が間違いに気づかなかったのだろう)




そういうわけで、最終的にプログラムは一カ所、1byte だけ書き換えられた。

「9」を「5」にしたのだ。これで動作して、安定している。



僕は、ここでの「長さ制限」自体が不要だ、と主張した。

データはバイナリ列のストリームで、「最後までの長さ」という概念がないはずだ。

にもかかわらず、長さで制限するのがおかしい。


実際、そんなおかしな前提だから、「次のデータがくっついたら動作する」などという、曖昧な処理になってしまうんだ。



しかし、データベースのインターフェイスは重要な根幹部分だ。

変更はできるだけ最小限が望ましい、というのが、発注元のプログラマの主張だった。



まぁ、その言い分もものすごくよくわかる。

1byte の変更で問題が解消する、というのは、最善の落としどころだろう。




▲目次へ ⇒この記事のURL

別年同日の日記

03年 美術と芸術

05年 確定申告

10年 八景島

12年 経験した中で最大のバグ

14年 雪・科学館・おゆうぎ会

16年 スティーブ・ブリストー 命日(2015)

19年 完全停止


申し訳ありませんが、現在意見投稿をできない状態にしています

BABA IS YOU  2020-02-27 12:58:33  コンピュータ

▲目次へ ⇒この記事のURL

中3の長男の受験は、先週中に終了した。


そこで、以前から僕が欲しかったゲームをやっと購入できた。

僕が遊んでいたら長男も気になるだろうし、受験終わるまで待ってたの。




BABA IS YOU。


1年くらい前に PC で発売されたゲームで、その時から興味を持っていた。

昨年末には Nintendo Switch で日本語版が出たので遊びたかったのだが、上に書いたような理由で我慢していた。



興味は持っていたのだが、基本ルール以外の情報があまり入ってこない。

というのも、これはパズルゲームであり、詳細を伝えるとネタバレになる恐れがあるためだ。



ここでも、読んでいる人が興味を持てるかどうかのぎりぎりの情報しか出さないようにしよう。

ネタバレすると困るから。




基本的には、倉庫番タイプのゲームだ。


主人公はマス目の中を動く。

障害物には、動くものと動かないものがある。

動くものは押せる。動くものの向こうに動かないものがあると、押せない。


倉庫番の場合、動くもの(荷物)が2つになっても押せなかった。

BABA IS YOU では、いくつでもいっぺんに押せる。



ところで、以前に僕はゲームに関する持論を書いたことがある。


ゲームのルールは、シンプルでなくてはならない。

しかし、状況は十分に複雑でなくてはならない。


ルールを複雑にすれば、当然状況も複雑になる。

しかし、それではルールに振り回されるだけで、楽しくないのだ。


すぐに把握できるほどシンプルで、それを駆使して複雑な状況を乗り切るのが楽しいのだ。


「倉庫番」は、過去に書いた日記でも、シンプルで複雑なゲームの代表として書いた。



しかし、BABA IS YOU は、シンプルといってよいのかどうかわからないんだ。


ルールはすぐに把握できる。上に書いたように、倉庫番と類似だ。

しかし、BABA IS YOU の特徴は、このルールの中で「追加ルール」を、ユーザーが自分で決められることなんだ。




最初の面はチュートリアルだ。


壁に区切られた、3マス分しかない細い通路と、主人公と思われる白い謎生物。

通路の途中には、道を塞ぐように岩が3つ並んでいる。

そして、岩の向こうには旗が立っていて、きらきらとしたアニメーションをしている。


倉庫番のように、通路を進んで岩を動かし、旗まで行くと「おめでとうございます」と画面に表示され、面クリアだ。



さて、面クリアしたら、もう一度同じ面を遊んでみよう。


通路の外には、単語が書かれたブロックが並んでいる。

4カ所にまとまっていて、それぞれは3つのブロックが組み合わさっている。

書かれているのは、次の通りだ。


BABA IS YOU

WALL IS STOP

ROCK IS PUSH

FLAG IS WIN


通路の外に主人公を動かして、これらの単語を押すと、動かせる。


例えば、 BABA IS YOU を動かして、並びを壊してしまうと…

あれ、主人公が操作できなくなる。しばらく待つと、画面上に「巻き戻す 最初から」と操作表示が出る。

つまりは、失敗してゲームオーバーのようだ。


BABA とは「主人公」だと思い込んでいた、白い謎生物のことのようだ。

それが「YOU」、つまり主人公である、と示している。


そして、この「追加ルール」を壊してしまうと、主人公がいなくなるためゲームオーバーとなる。


WALL IS STOP を壊せば、壁はすり抜け可能となる。もはや、ただの背景だ。

組み換えも可能で、ROCK IS WIN にすると、岩がきらきらし始め、そこに行くと「おめでとうございます」となる。


さらには、WALL IS ROCK とすれば、画面上の壁がすべて岩に変わる。



単語は、縦に並べてもいい。

ただし、左から右、または上から下に解釈される。逆順にはならない。


    ROCK
BABA IS YOU
    PUSH

と並べると、IS を共有して、2つのルールが完成する。

こうやって「単語を節約する」必要があることも多い。


ちなみに

WALL
 IS
BABA IS YOU


のようにすると、画面上の WALL が全部 BABA になって、キー操作で同時に動く。


        WALL
         IS
BABA IS YOU


だと、WALL がそのまま「主人公」に追加される。

BABA にはならないが、キーで同時に動く点は同じだ。


画面上のものがたくさん同時に動くのは、結構カオス。

見た目だけでなく、繊細な操作を必要とされるパズルゲームで、数の暴力を展開すると恐ろしいことになる。

(それが必要な面だってある)




DOOR IS SHUT AND STOP

KEY IS OPEN AND PUSH


とか書かれていたとする。(実際、これは多いルールだ)


ドアは閉まっていて、障害物。

鍵は開いて、押せる。


ここで、OPEN に対応するのが SHUT だ。

鍵を押してドアにもっていくと、開く。この時、ドアと鍵が同時に消滅する。


一方で、


WATER IS SINK


というのもある。「水は沈む」だ。

この場合、水に入ったものはなんでも消えてしまうが、同時に水も消える。

SHUT と OPEN は2つでセットだが、SINK は相手を選ばない。

しかし、「2つセットにすると消えてしまう」という現象は同じだ。



ここではさらっとルールを書いてしまったが、ゲームをしていて説明されることはない。

新しい単語を見かけたら、それがどういう意味か、実験しながら推察していくしかないんだ。



このゲームの面白さの多くの部分が、そうした「実験と推察」だ。

倉庫番のようなルールだけど、じっくり考えてわかるものでもない。

知らない仕掛けが次々登場して、その仕掛けの意味を調べつくし、それらをどう組み合わせれば目的を達成できるのか考える。




倉庫番なので、壁の角に押し付けられたブロックは動かせない。

ゲーム内では、これを利用して「変えられないルール」を作り出していることも多い。


もっと言えば、入り込めない壁の奥に書かれているルールは、不可侵だ。

変えられないだけでなく、その単語を利用することすらできない。


その一方で、壁に囲まれていて不可侵に見えるブロックを、「壁」自体の定義を作り変えて入り込んで利用する…というような面もある。


とにかく自由すぎる。

そして、自由かと思っていたら、どうしようもなく組み替えられないルールに悩まされ、不自由を感じたりする。


不思議極まりないゲームだ。




これは、一種の「プログラムゲーム」なのだと思う。

プログラムゲームとは、一定のアルゴリズムなどを記述することで遊ぶタイプのゲームだ。


戦闘アルゴリズムを書いて対戦する、なんてのが多いけど、ヒューマン・リソース・マシーンみたいな課題クリア型もある。


BABA IS YOU では、長いプログラムを組めるわけではない。

しかし、ゲーム内の文法に従って「記述」を行うことで問題を解決するし、その「記述」を複数組み合わせることで効果を持つ。


十分にプログラムだと言ってよいだろう。




購入前は、ルールを自分で変えられてしまうというので、比較的緩く遊べるパズルゲームを想像していた。


しかし、思っていた以上に難易度は高めだ。

その原因の一つは、新たな効果を持つ単語が出現した時に、その作用を十分に理解しないといけない、という点がある。


このゲームのルールが、シンプルといってよいのかどうか、最初に迷っていたのもその点だ。


基本ルールは非常にシンプルでありながら、単語の組み合わせ方は非常に幅広く、その効果も複雑だ。

この複雑さは、プログラムの複雑さと同じだろう。時にはバグも発生し、デバッグに悩まされる。


場合によっては、効果だけでなく、「効果による副作用」まで理解しないといけない。


そして、それらに対する説明は、どこにもない。

自分で実験しながら探し出さないといけない。


いわゆる「パズルゲーム」の難しさにとどまらず、「なにかを研究する」難しさに近いといってよいだろう。



先週末に購入し、長男が熱中して遊んでいるので僕はなかなか遊べず、まだあまり先の面を見ていない。

先の面を見るのが楽しみだ。


じっくりと考えることが好きな人には、自信をもってオススメできる作品。



▲目次へ ⇒この記事のURL

別年同日の日記

02年 2/27

12年 おゆうぎ会

15年 WING WAR


申し訳ありませんが、現在意見投稿をできない状態にしています

【訃報】ジョン・ホートン・コンウェイ氏  2020-04-15 18:22:50  コンピュータ 今日は何の日

▲目次へ ⇒この記事のURL

数学者の、ジョン・ホートン・コンウェイ氏が、11日に新型コロナウィルスによる合併症で亡くなったそうです。



…さて、僕は氏のことをほとんど知りません。

それでもここで取り上げるのは、「ライフゲイム」の考案者だからです。




あえてライフゲイムと書くのは、日本に最初に紹介した本が「ライフゲイムの宇宙」というタイトルだったため。


まぁ、一般的には「ライフゲーム」です。

ただ、英語で The Game of LIFE といえば、一般には「人生ゲーム」のこと。

そのため、「コンウェイのライフゲーム」とも呼ばれます。



で、そのライフゲームが何なのかといえば、「生物群をシミュレートする初期の方法」であり、「セルラーオートマトンの初期のもの」です。



非常に単純なルールで、生物群の存在をシミュレートします。

ここでグダグダルール書いたりしても面白くないので、興味持った人は自分で調べてください。


ルールは単純なのですが、非常に広い範囲…理想的には、無限の広さを持った盤面の、1マス1マスにそのルールを適用する必要があります。

1回適用すると「1世代」と呼ばれ、最低100世代くらい繰り返すと面白みが出てきます。


とすると、無限の広さは無理なので 100x100 の盤面だとして、同じ操作を 1000000 (百万)回くらい繰り返す必要があります。

人間が手動でやるのは、とてもじゃないが無理。



でも、ルールは単純なので、初期の… 1960~70年代くらいのコンピューターを使い、研究されました。


特に中心的に研究していたのが、ビル・ゴスパー。

当時 MIT の学生で、自由に使えた PDP-6 でライフゲイムの研究を行っていました。


ここらへん、時々僕が名著として挙げる「ハッカーズ」の中に、1節丸ごと使って様子が描かれています。


彼は、コンウェイ自身が「存在しそうだけど見つけられない」という、「永久に増え続けるパターン」を見つけ出そうと一生懸命になり…ついに見つけ出し、コンウェイの懸けた懸賞金 50ドルを勝ち取ります。



今でもライフゲームの研究者はいて、続々と新発見が報告されたりしています。


単純ですが、非常に奥深い世界です。




全然関係ない話題なのだけど、昔、私鉄の自動券売機の表示画面でライフゲームが動いているのを見たことがあります。


当時は今とは違い、細かな LED 表示のディスプレイだったのですが、長い間同じ表示を出し続けていると、点灯時間が長い LED から寿命が尽きてしまいます。


なので、誰もいないときは表示を消すと良いのですが、消してしまうと電源が入っていないようにも見えます。



そこで、「動いている」ことを示しつつ、常にランダムに動き続ける模様として、ライフゲームが使われたようなのです。


人感センサーがついていて、近づくと普通の表示に戻るようになっていました。




ライフゲームに類似なものを、セルラーオートマトンと呼びます。

「マス目に区切った世界に対し、一定のルールを適用し続ける」ものです。


「セルラー」の語源は、生物の細胞、セル。

実際、生物の細胞は同じような仕組みで動いているかもしれない…という研究報告もあります。


ヒョウ柄とか、トラ柄とか、キリンの柄とか、熱帯魚の柄とか。


あれ、遺伝子で柄が指定されているわけではないです。「偶然」で出来上がっている。

でも、この偶然の指定は、遺伝で決まっている。


その偶然の指定が、どうもセルラーオートマトンのルールみたいになっているようなのです。

ライフゲームのルールをちょっと変えて適用してやると、いろいろな動物の柄に似たものが浮かび上がってきたりします。


こうした研究も、コンウェイのライフゲームの研究の上に成り立っているものです。




セルラーオートマトン自体は、マス目に区切った世界にルールを適用し続けるものなのですが、ここから派生して「人工生命」という研究も生まれました。


コンウェイのライフゲームは、非常に単純なルールを適用するだけで、生物の「ようにみえる」状況を生み出すものでした。


でも、もう少しちゃんと「生命らしい」ものを作ってみたら?


マス目にルールを適用するのではなく、生命としてふるまうプログラムを作って、いろいろな研究をするのが「人工生命」の分野です。



遺伝的アルゴリズムとか、人工生命分野から生まれた発想で、今では別の分野でも使われます。


「少しづつ違ったランダムパラメーターを用意して、それらどうしを戦わせ、優れたものだけ残していく。

 残った者同士のパラメーターをかけ合わせたり、ランダムに突然変異を入れたりしながら、さらに強いものを残す。

 最終的には最強のパラメーターが出来上がる」


という考えかた。


例えば、2000年を過ぎたころから、急にチェスや将棋、囲碁の AI が強くなってきたのは、この考え方を取り入れたためです。





まぁ、僕はこうした世界は「好き」ではあるのですが、研究者ではないので薄っぺらな知識しか持っていません。


亡くなったコンウェイ氏の業績としては、ライフゲイムなんてのは「ほんの僅かな手遊び」みたいなもので、非常に偉大な数学者だったようです。


でも、そちらについても僕はちっとも理解していませんので、紹介できません。



しかし、ライフゲイムだけでも、上に書いたように後に続く様々な研究の礎となっているわけです。


▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

今日は何の日

別年同日の日記

02年 4/15

15年 PC-E500 発売日(1988)


申し訳ありませんが、現在意見投稿をできない状態にしています

Chromebook を買ったのだけど  2020-05-21 10:57:05  コンピュータ

▲目次へ ⇒この記事のURL

4年前に購入したChromebookが、壊れかけている。


キーボード手前に配置されているタッチパッドのスイッチ部分がおかしく、接触しっぱなしになってしまうのだ。

マウスでいえば、左ボタンを押しっぱなしにした状態。


で、外付けマウスをつけていても、左ボタン押しっぱなしと判断されてしまうため、左クリックできない。

タッチパッドのスイッチのあたりをガチャガチャやると治るのだけど、また不意におかしくなったりする。



昨日も書いたが、子供たちの学校がネット授業も開始する予定だ。

現在、親の古いマシンも含め、子供たち一人に1台のPCはあるのだけど、1台はこの Chromebook なのだ。




ちょっと問題あるよなぁ、と、買い替えを検討したのはもう1か月ほど前。

しかし、このご時世で手ごろな値段の PC は軒並み売り切れだった。

Chromebook もご多分に漏れず。



それが、学校から「近々ネットでの授業を開始する」という連絡が来たので、再度調べたのが先週末。

性能的に申し分なく、値段も2万5千円ほどという悪くないマシンが Amazon にあったので、購入した。


しかし、僕の確認不足だったのだ。



今週前半に届いたマシンは、US キーボードだった。

見直したら、ちゃんとそう書いてあった。


うーん、残念だけど、返品。

手続きはして、まだ送付していない段階。


他にいいマシンはないか調べたけど、手ごろな値段のマシンは軒並み売り切れで、今入手できるのは高価なマシンになってしまう。



仕方がないので、もう少し待つか…



▲目次へ ⇒この記事のURL

関連ページ

Lenovo Ideapad C340 購入【日記 20/08/22】

別年同日の日記

03年 楽園を求めて…

05年 お掃除ロボ

12年 姪の結婚式

15年 68000はグラフィックに強かったのか

18年 フェスとフェスタと祭りと開放日

19年 あーすフェスタ


申し訳ありませんが、現在意見投稿をできない状態にしています

ENIAC vs 6502  2020-06-19 18:54:40  コンピュータ

▲目次へ ⇒この記事のURL

つい先日、Twitter で「ENIAC はマイコンでどの程度か」とつぶやいている人がいた。


なるほど。ENIAC の性能というのは時々話題になるのだけど、僕も詳細に性能比較をしたことは無かった。

概念から違いすぎて比較は無理、という気もするが、遊び程度にやってみるのも面白そうだ。



▼前提知識


概念から違う、と書いたのだけど、ENIAC の計算方式について、ざっくりと前知識。

まず、ENIAC は最初のコンピューターとされることが多いのだけど、現代のコンピューターとは計算方法が全然違う。


2進数か 10進数か、という違うもあるのだけど、それ以上の違いがある。

ENIAC は「どんな複雑な計算式でも、微分を繰り返すと足し算になる」ということを利用して、方程式をひたすら数値計算で解くためのシステムだ。


古くは、チャールズ・バベジの階差機関・解析機関が同様のアイディアを持っていた。

ただし、実現できていない。


ENIAC 以前には、歯車とモーターで実現したハーバード・マーク1があった。


ENIAC は、計算のアイディアとしては全く同じままだが、物理部品を無くして電気化することで、超高速の演算を実現しようとした。



▼ENIAC の計算能力


歯車を模倣しているので、2進数ではない。

10進数 10桁の加算機が電気回路で表現されていて、この装置が 20台ある。


1台の加算機は、毎秒 5000回の加算ができる。

これが 20台並列動作するので、ENIAC 全体としては、1秒間に最大 100000回(10万回)の加算ができる。



▼比較対象の選定


というわけで、現代のマイコン代表。

3つの理由があり、ファミコンを比較対象としたい。


もっと細かく書くと、ファミコンの CPU である 6502 が比較対象だ。


メモリ搭載量や動作周波数はファミコンに倣う。

しかし、主に計算能力の比較とし、ファミコン全体の性能を見るつもりはない。



ファミコンを選ぶ理由の1つ目は、有名でありながら、十分に低性能だからだ。

そもそも ENIAC が「世界初」のコンピューターであり、性能を期待できない。

現代の CPU と比べたら、差が大きすぎて面白くもなんともない。


ファミコンはもう40年前の機械だけど、知名度はいまだにある。

知らないはずの世代でも、Switch のエミュレータを見たことくらいはあるだろう。



もう一つの理由だが、僕個人の記憶で、確かファミコン現役当時のベーマガ(当時人気のあったパソコン雑誌)に、「ENIAC はファミコン程度の能力しかなかった」と書かれていた気がするのだ。


記憶にすぎず、ベーマガではなく別の雑誌だったかもしれない。

でも、「ENIAC はファミコン程度」という言葉を知っている人はいるようで、Yahoo知恵袋でもそういう質問があった


「ファミコンの方が圧倒的に高性能」という答えがベストアンサーになっていたのだけど、圧倒的というほどなのか調べたい気持ちもある。



3つ目、最後の理由だ。

冒頭で書いた Twitter でつぶやいていた人は、僕の書いたページ「Z80 vs 6502」の URL をツイートしてくれていたのだ。

だから、エゴサーチで見つけたのだけど。


該当ページは、MSX の CPU としての Z80 と、ファミコンの CPU としての 6502 の速度比較を行ったものだった。


じゃぁ、その 6502 と、ENIAC を比較してみようじゃないか。



▼ファミコンの計算能力


6502 CPU は、8bit 計算しかできない。

しかも、同時並列の計算能力もない。ENIAC に比べると、ずっと低性能だ。


しかし、ENIAC と違い、柔軟なプログラム能力がある。

プログラム能力の違いは後で詳細を書くが、計算は「1回に」 8bit しかできないが、繰り返すことで、もっと大きな数値を扱うことも可能だ。


さて、ENIAC の 10進10桁の記憶能力は、2進数だと 34bit 相当になる。

しかし、8bit を単位とする現代の CPU では、ちょっと中途半端な数値だ。


ここは、少し足りないが 32bit で計算させてもらうことにしよう。

(これだと、10進数にして9桁が計算の限界となる)



6502 では、先に書いたように1度の計算は 8bit しかできない。

もっと大きな bit 長の計算をしたい場合は、メモリに置いた数値同士を足すことになる。


そこで、メモリ同士の足し算を示めそう。


LDA >1 ; 3

ADC >0 ; 3

STA >0 ; 3


何ことやらわからないかもしれないが、これが「1番地の数値を、0番値に足す」というプログラムだ。

; の後ろに書いてあるのは、必要な時間だ。単位は「クロック」。足し算には 9クロック必要と分かる。


これで 8bit の計算が終わるが、値を保持するメモリ番地を変えながら単純に4回繰り返せば、32bit 分の計算になる。


というのも、6502 の足し算は「前の足し算の繰上りも足す」ようになっているからだ。

繰り返し計算をしたことで、ひっ算のように「上の桁」を計算していったことになる。


ここまでで、36クロック。


しかし、ちょっと待って欲しい。

繰上りを一緒に足している、ということは、一番最初の計算はおかしなことにならないか?


そこで、最初に「繰上りを消す」という前処理を入れないといけない。


CLC ; 2


これだけでいい。

合計 38クロックで、32bit の足し算が終わる。

これが、6502 の計算能力だ。


では、これは実際どの程度の速度なのだろう?


ファミコンの場合、1.79MHz のクロックが使われている。

これは、1秒間が 1790000クロックだ、という意味だ。


38クロックで割ると、47105 という数が出てくる。

これが、ファミコンで1秒間に行える、32bit 足し算の回数だ。


▼計算速度比較


ENIAC は1秒間に 10万回の10進数10桁加算が行えた。

一方、ファミコンは1秒間に 4万 7千回ほどの 32bit 加算が行える。


計算できる桁数はほぼ同等と見なして、ファミコンは ENIAC の半分程度の性能だ。



まぁ、実際にはどちらもピーク性能を出すことは難しかったと思うが、並列演算を使いこなす方が、順次演算を使いこなすより難しい。


この点で、「実効性能」で見たときは、ファミコンと ENIAC は同等、というのはそれほど間違っていないように思う。



▼メモリ搭載量


現代的には、プログラムはメモリに格納するし、処理対象のデータもメモリに格納する。

処理後の結果も一時的にメモリに置いておき、後でまとめて示したりする。


とにかく、メモリはコンピューターに不可欠の存在となっている。



しかし、ENIAC の時代は違う。


ENIAC は数式の「計算方法」をプログラムできる。

このプログラムとは、加算機の保持するデータを、別の加算機に加算する…というのを、配線で示すのだ。

つまり、プログラムにメモリは必要ない。


数式に入れる初期データは、パンチカードの束で示される。

結果は直接印字されるか、一旦パンチカードの束として出力され、カード集計機でソートなどの処理を行ってから、別の機械で印字された。


つまり、データを保持するためのメモリは必要ない。

または、パンチカードという「外部メモリ」を、必要に応じていくらでも使用できる。




ENIAC の持つメモリとしては、まず加算装置だろう。

先に書いた通り、10進数 10桁 20本。


今回は、32bit (4byte) ということにしているので、全部で 80byte 。

これが書き換え可能な全メモリだ。



ところで、ENIAC は先に書いたように、数式の微分を繰り返すと、足し算に分解される性質を利用して計算を行う。

しかし、三角関数などは、微分しても足し算にならない。


そこで、これらは「数表」を使って処理する。関数の結果表を用意して、その数値を使うのだ。


このための「数表装置」は 10進数 6桁 の数値を、204本設定できた。

この装置は 3台あった。


10進数 6桁は、20bit で表現できる。ここでは、24bit (3byte) としておこう。

すると、1台の数表装置は、 3*204 = 612byte のメモリ、ということになる。

3台で 1836byteだ。


これは、現代的には ROM に相当する。




一方、ファミコンは 2048byte の RAM を搭載している。


6502 の特性上、256byte は計算時に使用する特別なメモリだ。

計算時に使用する、ということで、ENIAC の加算機の容量に相当するもの、と思ってもよい。


また別の 256byte は、スタックという、これも特別なメモリとして予約される。


自由に使ってよいのは、残る 1536byte だ。


さらに、プログラムなどは最大 32Kbyte の ROM に格納された。

固定データも ROM に入れることができる。




先に書いた通り、ENIAC の時代にはメモリは「必要とされなかった」。

だから、メモリ量の大小は、比較の優劣とはならない。


それでも「ファミコンの方がメモリがあった」と思う人はいるかもしれない。

しかし、ENIAC はデータ入出力にパンチカードが使えたことを忘れてはならない。


これは読み書き自由な記憶装置で、必要であれば無制限に使えた。

水爆の設計計算の際には、100万枚のカードが使用されたそうだ。


データ処理能力、という点で見れば、ENIAC は高い能力を持っていた。



▼プログラム能力


何度も書くが、ENIAC はひたすら加算を繰り返すことで、目的の値を得るためのシステムだ。

だから、プログラムというのは「どのデータを、どのデータと足すか」をひたすら示すことになる。


先に書いた通り、ENIAC は配線によってプログラムを行う。

あくまでも「どこを足し合わせるか」など、結び合わせたい対象を、配線で結ぶだけだ。


配線でプログラムした、という話を、ENIAC を分解して論理回路を組みなおしたようにとらえている人もいるようだが、そんなに複雑ではない。


加算をひたすら繰り返す、というのが ENIAC の基本なので、「繰り返し」は当然だった。


プログラムは複数作ることができて、計算結果を条件にして、どのプログラムを使用するか選ぶこともできた。


例えば、弾道計算では、風速や空気抵抗なども考慮しながら弾の高度・距離を計算していき、高度が「マイナスになったら」という条件で、その時の距離の数値を印字する、などの動作ができる。


さらに、印字後には次の初期条件をパンチカードの束から読み込み、再び計算開始…


などとしておけば、用意した初期条件の計算をひたすら繰り返し、結果を印字し、弾道計算表を作り出すことができた。



しかし、ENIAC のプログラムは、その程度だ。

基本的に、1つの数式に基づいた計算を、条件を変えながらひたすら繰り返す機械だ。


ENIAC は「高速計算機」であり、現代的な意味でのコンピューターではない。




ファミコンは、現代的なコンピューターだ。

多くの説明はいらないだろう。ファミコンのプログラムは、現代の多くの人が考えるプログラムと同じだ。


数値計算だけでなく、複雑な条件による「処理」ができる。

マリオがノコノコを踏んだら、甲羅が滑っていく…というのは、数式1本の処理ではないが、ファミコンなら難なく処理できる。


コンピューターを、なんでも処理できる機械としてとらえるなら、明らかにファミコンの方が能力が高い。



もっとも、これは後出しジャンケンだ。

ENIAC は高速な計算機として作られているので、「計算以外できない」のは当たり前だ。



▼まとめ


以上、ファミコンの 6502 と ENIAC を、無理やり比較してみた。


計算能力、メモリ搭載量、プログラム能力の3つの指標で比較しているが、当然のことながら、計算能力以外は比較することすらできない。


そして、計算能力だけでいうと、ENIAC の方が倍くらいの性能があった。



実は、比較前はファミコンの方が能力が上だと思っていた。

比較して10倍の性能差がなければ「同等」と認めた記事にしようと思っていたのだ。


でも、調べたら ENIAC の方が倍くらい高速だった。

だから「それ以外」の比較もしたのだけど、こちらは概念が違いすぎ、比較することができなかった。


とはいえ、一長一短あるので、能力として「ファミコン程度」というのは妥当な表現のように思う。



知恵袋で「ファミコンの方が圧倒的に高性能」と書いた人は、何を根拠に書いたのかわからない。

まぁ、以前も書いたのだが、あのような Q&Aサイトは信用してはならないものだと思っている。



なお、僕は ENIAC を現代的な意味での「コンピューター」としては認めない立場だ。


あくまでも「現代的な意味での」ね。

その違いが分かっていれば、世界初のコンピューターと呼んだってかまわない。


▲目次へ ⇒この記事のURL

関連ページ

ENIAC

別年同日の日記

04年 お父さんのための出産教室

06年 夏至祭

08年 ルータ変更

13年 報告書の書き方

14年 ブレーズ・パスカルの誕生日

15年 トーマス・J・ワトソンの命日(1956)

15年 パンク

19年 飲み会二つ


申し訳ありませんが、現在意見投稿をできない状態にしています

phpSpreadsheet で小数点付き数値と見なせる文字列を入力するとおかしくなる  2020-07-17 18:28:24  コンピュータ

▲目次へ ⇒この記事のURL

また、えらく重箱の隅つつきな話です。

バグとして報告したいところだけど、やり方わからないからとりあえず書き留めとく。




現在行っている仕事で、「データをExcel出力」している個所がある。

まぁ、よく見るね、こういうの。


サービスの主要部分は node.js で作成している。

サーバー側で javascript を動かす仕組みだ。


でも、Excel 出力する部分は、PHP でやっている。

node に良いライブラリがなく、phpSpreadsheet というライブラリが良い、と担当者が判断したためだ。


(少なくとも、xlsx と xls の両方出力でき、細かく装飾されたシートを出力できる必要があった。

 ただこれだけの条件で、できるライブラリは非常に限られている)


担当者が、と書いた通り、僕はこの部分の担当ではなかった。

でも、バグが報告され、その時担当者が忙しかったために、僕が原因を調べることになった。




具体的には、「文字列」として入力された、小数点を伴う数字を複数 Excel のセルに含めようとしたところ、

正しい値が入らずにぐちゃぐちゃになった。


最初は何が起きているかわからず、いろいろなデータを入れて試したところ、次のようなことが分かった。


・小数点を伴う数値と見なせる文字列を複数のセルに記載した場合、同じ整数部を持つ、先に入れたセルの内容が、後のセルの内容にコピーされる。


何を言っているのかわからないだろうから、実例。


0.1 / 1.1 / 0.2 / 1.2


という4つの数値があったとしよう。これは以下のようになる。


0.1 / 1.1 / 0.1 / 1.1


「同じ整数部を持つ、先に入れた内容が、後のセルにコピーされる」というのは、こういうことだ。


整数部が同じであれば全部同じ内容になってしまう。


数値としてみなせない文字列であれば、このような問題はない。

また、小数点を含まなければ問題はない。


数字だけの文字列でも


0120


のようなものも問題はない。




phpSpreadsheet は非常に高機能なライブラリだが、遅くてメモリ食いだ。

というのも、このライブラリは、「エクセルの読み書き」だけでなく、本当にスプレッドシートの中身を実現しようとしているため。


で、遅さをカバーするためにも、データはまとめて入れることが推奨されている。


fromArray というメソッドでデータをまとめて入れられる。

applyFromArray というメソッドで、セルの装飾データなどをまとめて与えられる。




そして、fromArray は高機能で、入れようとしたデータを自動的に識別し、正しく扱ってくれる。


= で始まるデータは、数式だ。セルの式をセットしてくれる。

数値として扱えるものは数値として入れてくれるし、そうでなければ文字列にしてくれる。


…ここで、文字列を与えたとしても、数値として扱えるものは数値になってしまう。


数値は、Excel 上「右寄せ」で表示される。文字列なら「左寄せ」だ。

文字列として入れたのに、右寄せになると格好が悪い。


そのため、担当者が作ったプログラムでは、データを入れた後で、セルに入っている値のデータを明示していた。

数値として入ったものであっても、「文字列」と指示すれば、文字列になってくれるようで、左寄せになる。



これは、Excel でいう「セルの書式設定」とは違うものだ。


セルの書式設定にも「文字列」とか「数値」があるのだけど、それはセル内部のデータを「書式設定のデータに変換して」表示する、という設定。


データの型を指定する、というのは、表示時に変換するのではなく、セルの中の値の型を指定するものだ。

そう、エクセルの値には型がある。恥ずかしながら、僕は今回の調査までそれを知らなかった。



phpSpreadsheet では、セルに入れたデータは、php としてのデータ型がある。

そして、それとは別に、セルの中の値の型を保持するようになっていた。


fromArray で入れた場合は、自動判別され、数値型であれば、php のデータとしても数値に変換され、セルの値の型も数値になった。

しかし、この後で「文字列型」と指定すると、php データは数値のまま、セルの値の型は文字列になった。




そして、出力の段階に至る。


これも知らなかったのだが、xlsx ファイルでは、セルの情報と、「文字列」情報は別に保持されている。

セルに文字列を入れる場合は、文字列へのポインタ(参照番号)が入る形、だそうだ。


これにより、同じ文字列が大量に入るような Excel ファイルは…非常に一般的だと思うが、データが圧縮されることになる。


ライブラリはセルの値の型が文字列型だった場合に、配列として対応表を作っている。

「文字列」に対して、「参照番号」を調べられる対応表で、出力時にこれを使って、同じ文字列には同じ参照番号を出力するのだ。


この時、「文字列」に対して、というのは、セルの値の型のことだ。

でも、実際の php のデータは、文字列とは限らない。


そこで、ライブラリのプログラムでは、「実際の php データが文字列か否か」で処理を分けている。

文字列の場合、ハッシュ関数を通して一意な数値を得て、それを引数として配列にアクセスする。

文字列ではない場合は数値なので、そのまま配列にアクセスする。



…ここにバグがある。

文字列ではない場合、数値ではあるが、整数とは限らない。

小数点を含む場合、php によって小数部分が切り捨てられ、整数化されたアクセスになってしまう。


結果として、小数点以下を含む値を文字列として扱おうとすると、同じ整数部を持つ値のコピーになってしまう。




回避方法。

fromArray でまとめて値をセットするのをやめればよい。


fromArray の中身は、setValue という関数を使い、ループで書き込んでいる。

この setValue は、入れられるデータを検査し、文字列であっても数値と見なせる場合は数値に変換する、などの高度な処理を行う。


これに対し、setValueExplicit を使うと、データを入れる際にそのセルの値の型を一緒に指定できる。

勝手な変換も行われない。


今回は、fromArray でデータを入れやすいように、データだけを配列としてあらかじめまとめてあった。

セルの値の型の指定は、後で行えるように別にまとめてあった。


なので、先にセルの値の型を指定してしまう。

セルに値が入っていなくても、型だけ指定できる。


その後で、自分で2重ループを作ってデータを入れる。


まず、セルの値の型を確認する。(getDataType でとれる)

型を指定していない場合は、文字列の "null" が返るので、この場合は setValue でデータを入れる。

null 以外が返っている場合は、データ型の指定があるので、setValueExplicit で型を指定してデータを入れる。


これで、勝手な型の変換はなくなり、想定していた型で入ることになる。

文字列型が指定されているのに内部が数値、などということもなくなり、おかしな挙動に悩まされなくなる。




phpSpreadsheet 、すごく動作が遅いし、ここに書いたような複雑怪奇な動作によるバグもある。

もっといいライブラリがあれば乗り換えるのだろうけど、


・xlsx 、xls の両方を出力できる。

・細かな装飾も行える

・計算式も含む、複雑な表を作れる。


などを満足するライブラリがなかなかないんだよね…


(PHP に限る必要はない。

 go の excelize はかなり良い線行ってそうなので少し試してみたのだけど、「既定のフォント」指定はできるのに、「既定のフォントサイズ」が指定できない、というかなり基本的な部分でダメだったよ…)




▲目次へ ⇒この記事のURL

別年同日の日記

02年 冷蔵庫に乾杯

14年 続・世界初のMML

15年 NECの創業日(1899)

15年 エジホン探偵事務所


申し訳ありませんが、現在意見投稿をできない状態にしています

リングフィットアドベンチャー  2020-07-27 15:32:16  コンピュータ 家族

▲目次へ ⇒この記事のURL

やっと入手できたので遊び始めた。

いま、1週間ほどやったところ。


先週末の4連休はどこにも出かけられなかったが、このゲームで家族中楽しめていた。





任天堂 Switch 向けのリングフィットアドベンチャーは、昨年の秋発売。


発売前は「色物なので様子見」と思っていた人が多いようだし、僕もそうだった。

しかし、発売直後から「面白い」と話題になり、入手困難に。


時々入荷の話題を聞いてはネットのショッピングサイトを探し、すでに売り切れている、という事実を確認する。


2度ほど、なんとなく覗いた Amazon で在庫を確認し、慌てて購入手続きをとるも「在庫なし」となっていた。

手続している数秒の差で売り切れてしまうのだ。それほどの人気商品。



で、年明けごろから中国でコロナウィルスの感染拡大があり、生産自体が止まってしまった。

4月ごろから再びわずかではあるが入荷するようになったが、多くは抽選販売。


抽選に応募し続け、やっと当たった次第。




ゲームについてはいろいろなところで話題になっているので、多くを書く必要はないだろう。


実際に筋トレなどにも使用される、弾力性の高いリングがコントローラーになっており、これを使ってゲームが進む。


Switch の Joy-con は左右1対あるが、左は太ももに括り付け、足の角度を測る。

「走る」とか「スクワット」とかは、足の角度を計測して行うわけだ。


右はリングに接続し、リングのたわみ具合を測るようになっている。

ここ、不思議なのだが、コントローラーに外部との接続端子があるのだろうか?



Wii リモコンでは、「ヌンチャク」をはじめとする外部機器を接続できるようになっていた。

だから、Joy-con でも外部機器が接続できても不思議はない。


そもそも、Bluetooth 機器としてのペアリングも「本体に装着」すれば完了するようになっているので、外部との連絡端子は何かしら持っているはずだ。




で、右 Joy-con は、たわみ具合を計測して送信するだけでなく、傾きなどのセンシングも当然行う。

だから、リングをどのような向きで持っているか、など計測できる。


これで、非常に多彩な動作をセンシングできるようになっている。



一番面白いと思ったのは(そして、あまりゲームレビューなどで見かけないのが)、Joy-con 右で脈拍を計測できること。



Joy-con 右には、もともと赤外線カメラがついている。

これを指に密着させることで、脈拍を測るのだ。


内部でどのように取れているのかはわからない。

おそらく、カメラに近すぎてピントはあっていないのだろう。


でも、赤外線なので、おそらくは血管が写る。

脈動に合わせて面積が広がったり縮んだりするので、それを「うまく」計測すれば、脈拍がわかる。



任天堂って、脈拍測るの好きだよね…


(N64 では「バイオセンサー」の名前で発売されたが、対応ソフトはテトリス64のみ。

 Wii では「バイタリティセンサー」として発表されたが、発売されなかった)



今回は、特別な外部機器なしに標準機能を工夫して測った、というところで感心した。




ゲーム自体は、一本道の RPG だと思ってもらっていい。


お話があって、道を進んでいくと(実際に足を動かし、走る必要がある)、敵と遭遇したりして戦いになる。


戦う方法は筋肉のトレーニング。


画面に指示されるとおりに行う。

左ももの角度と、リングコントローラーの組み合わせだけで、いろいろな筋トレをセンシングし、まじめにやっていれば相手に大きなダメージを与えられる。


(決して力が問題ではなく、まじめにやっていればいい)



この攻撃方法も、ちゃんと RPG らしく、旅の途中で「強い攻撃」を手に入れられる。

1体だけに強い攻撃、とか、弱めだけど3体同時攻撃、とか。

敵との「相性」で攻撃力が上がったりもある。


そういうことを考慮し、自分で選んで、指示通りに筋トレすれば攻撃できるわけだ。

適度に考えて、適度に体を動かして、狙い通りに敵を倒せれば楽しいし、あと少し攻撃力が足りなくて倒せないと悔しい。



で、自分の攻撃が終わると、敵の攻撃のターンだ。


これは基本的に、腹筋でガードする。攻撃のように選んだりはできない。

リングを両手で腹に押し当て、大きくたわませれば強いガードになるのだけど、しっかり腹筋を固くしていないとたわまないのだ。




トレーニングの負荷量は自分で選べるし、毎日「前回の運動はきつかったか」など聞かれ、調整される。

最初は軽い感じから…と始めたが、それでも3日目には軽い筋肉痛になった。


というのも、普段使っていないような筋肉も使うから。

で、3日目の筋肉痛を超えたら、同じ負荷では物足りなくなったので、少し負荷を上げた。


以降、筋肉痛にはなっていない。

それなりの運動量だとは思うし、毎日30分程度ゲームをやると「もう今日はここまでにしとこう」と思うくらい疲れる。

(ちょうど、それくらいでゲームから「今日はここまでにしませんか?」と聞かれる)



疲れるのだけど、辛くはない。

筋トレって、普通は「自分の筋肉を鍛える」ことを目標にやるのだと思うけど、すぐに目に見えるほどの効果が出るわけではないので、挫折しやすい。


そこを、「先のストーリーが気になる」という別の目的に変えて、楽しみながらトレーニングできるようにしてある。




移動中、リングを「押し込む」と空気を吐き出して空気砲で周囲のものを攻撃できる。

逆に「引っ張る」と、空気を吸い込んで、周辺のアイテムを取得できる。


道端に箱があれば、空気砲で壊してアイテムを入手できる。

でも、アイテムが直接落ちていれば、吸い込まないといけない。


さらに、下に向けて空気砲を出すと、ジャンプできる。

押し続けていればホバリングも可能だ。


そして、一番大切なこと。

速く走るとトレーニング効果が高い。

これは、ゲーム中では早く「レベルアップ」して、強くなることを意味する。



結果、早く走って目まぐるしく変わる景色の中で、周囲のアイテムを見極めて、リングを押したり引いたり、結構忙しいゲームなのだ。


敵との遭遇時などは、筋トレの体制が整うまでいくらでも待ってくれる。

でも、移動中は、単純だけど忙しいアクションゲーム。


ここら辺のバランスもうまくできていて、適度に楽しみつつ、適度に悔しがりつつ遊ぶことができる。




元々僕は運動嫌いなのだけど、独立して自宅で仕事を始めたころから、「体が資本」だと考えるようになりました。

健康に気を使って、時々走ったりしています。


と言っても、やっぱりめげるんだよね…もともと好きではないから。

夏の暑さに負け、冬の寒さに負け、走るのは春秋のわずかな期間だけ。


「こんなんじゃいかんよなぁ」と思って、家事をしながら中腰で足腰を鍛えたり、本を読みながら上半身を傾けて腹筋を鍛えていたりすることもあるのだけど、それだって毎日ではない。



運動嫌いとはいえ、やってないわけではないので、「急にやると辛いだけ」というのは知っています。

だから、負荷は軽めにして、毎日楽しむことを優先している。


リングフィットも、入手したけど筋肉痛で挫折した…というような話も聞きます。

筋トレに慣れていない人が「身体鍛えるぞ!」って頑張りすぎると、そうなりそうだと思う。



僕もまだ1週間で、最後まではやっていません。

途中で挫折しないように頑張りたいと思います。



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

家族

別年同日の日記

02年 誕生日!

11年 節電その後

12年 続・理系と工学系

14年 NTSC PAL SECAM


申し訳ありませんが、現在意見投稿をできない状態にしています

Windowを閉じるボタンの左右位置  2020-08-17 17:54:40  コンピュータ

▲目次へ ⇒この記事のURL

6年も前に書いた「ボタンの左右位置」の話は人気で、今でも時々参照される。


スマホ、Mac 、Windows で OK Cancel ボタンが並ぶときに、どちらが左に来るか?

なぜそうなっているか? を解説した記事だ。



iPhone と Mac は、OK が右に来る。

Windows は OK が左に来る。


Android は最初期のころは Windows を真似ていたが、現在は iPhone と同じだ。


Windows は Mac を真似して作ったが、真似だと言われないように逆にしたのだ、という噂がある。


でも、それはでたらめだ。

Windows で OK が左になっているのは、ちゃんと理由がある。




この記事が先日も参照されていたのだが、その人は「ウィンドウを閉じるボタンの位置」を気にしていた。



MacOS では、閉じる・最小化、最大化ボタンはウィンドウの左上についている。

それに対し、Windows では右上についている。


ここでまた、「Mac の逆にしたのでは?」説が出ていた。


いや、それもそんな理由ではなく、ちゃんとした歴史的経緯があるのだ。


因縁話ばかりしていると老人の仲間入りだとは思うが、ネットを探すとこうした情報があまりないようなので書いておこう。




まず、MacOS が「閉じるボタンが左上」なのは良い。これは初代から変わらない。

でも、その他のボタンも左上になったのは、MacOS X からだ。 MacOS 9 までは違った。


初期から 7 まで、拡大ボタンは右上についていた。

左に閉じるボタン、右に拡大ボタン、という左右対称デザインにしていたのだ。


最小化、という概念はなかった。

なぜなら、MacOS はシングルタスク OS であり、最小化して「何も画面に表示しない」ことに意味がなかったためだ。



その後、System 7 (MacOS 8 以前は、単に System と呼ばれていた)の時にマルチタスク動作が可能になり、ウィンドウがたくさん重なる状態が邪魔になった。


そのため、7.5 で「ウィンドウシェード」という機能ができた。


「窓」にかかるシェードカーテンのように、巻き上げられる機能だ。

具体的には、タイトルバーだけに「最小化」される。


この機能は、タイトルバーをダブルクリックすることで行われる。新たなボタンは設定されない。

本来、Mac では「ダブルクリックは開く」という操作だったのだが、ダブルクリックでウィンドウを「閉じて最小化する」というおかしな操作だった。


当初考えていなかったマルチタスクが搭載されたための、苦肉の策だ。



MacOS 8 では、シェードのためのボタンを増設し、右端に付けた。

並びは拡大、シェードの順で、閉じるボタンが左端なのは変わらない。


いろいろと操作が混乱して、扱いにくくなったため、MacOS X になった時に大幅に UI が改められ、ボタンが全部左に寄せられた。


これが、現在の MacOS X の形になる。




Windows 1.0 は、左上に閉じるボタンがあり、右上に最大化ボタンがあった。

つまり、Mac と同じだ。真似と言われないように逆に、なんてことはしていない。


ただし、「閉じるボタン」は、閉じる以外の機能も持っている。

つまりメニューボタンなのだけど、一番重要な機能は「閉じる」で、ダブルクリックで閉じられた。


ダブルクリックは、Mac では基本的に「開く」という操作だとされた。

それに対し、Windows では「示したオブジェクトの、一番よく使う操作」だ。


ファイルアイコンで一番使う操作は、開くこと。

メニューで一番使う操作は、閉じること。


そういう操作体系であり、ダブルクリックで閉じることを混乱だとはとらえない。



しかし、Mac と違って、最初からマルチタスクだった。

そのため、画面上に多数のウィンドウが表示された。


ごちゃごちゃして邪魔なので、2.0 で最小化ボタンが追加された。

このボタンは、右端の拡大ボタンの隣に設置された。

この時「拡大」ボタンは「最大化」ボタンと名称変更した。最小と最大、という統一感を出したのだ。


(MacOS 9 でシェードが追加されるよりも前の話だ)


まぁ、多くの人が見たことがあるのは、3.0 以降だろう。

ここでも見た目は変わらず、左上に事実上「閉じる」ボタンである、メニューボタン。

右端に最小化と最大化が並ぶ。



このデザインが大きく変わったのは、次の Windows 95 になった時だ。

「閉じる」ボタンの機能はよく使うので、ダブルクリックしなくてもよいように、左上のボタン群に追加された。

ここで初めて「最小化・最大化・閉じる」の3つボタンデザインができる。


(MacOS X の登場はずっと後だ)



左上のボタンは、一見廃止されたように見えるが、「プログラムのアイコン表示」という形で残った。

見た目はボタンではないが、押すとメニューが出るし、ダブルクリックで閉じるのだ。


実は、この機能は今でも残っている。

タイトルバーを消してしまっているような特殊なソフト…Chrome などでは動かないけど、タイトルバーがあり、左端にプログラムのアイコンが表示されているウィンドウでは、アイコンダブルクリックで閉じる。


だから、「Windows の閉じるボタンは右で、Mac と逆になっている」というのが間違いだ。

今でも Windows の閉じるボタンは、左にも残っている。





余談になってしまうが、なぜ Windows で、「ダブルクリックで閉じる」なんていう面倒な操作を標準としたのか書いておこう。


これは、Mac と Windows の「プログラム」に対する観念の違いに起因するものだ。


Mac では、ウィンドウを閉じてもプログラムは終了しなかった。

Windows では、ウィンドウを閉じるとプログラムが終了した。


「プログラムの起動」はコスト(=時間)のかかる処理なので、うっかり終了してしまうのはよくない。

そのため、閉じる操作を「クリック」ではなく、「ダブルクリック」としていたのだろうと思う。


その頃の Windows では、1つのプログラムは、基本的に1つのウィンドウを使用した。

複数のウィンドウを開きたいときは「ウィンドウ内ウィンドウ」を使うようになっていた。



これが改められたのが、Windows 95 から。

1つのプログラムで、複数のウィンドウが開けるようになった。

プログラムを終了するには、メインウィンドウを閉じるか、すべてのウィンドウを閉じる必要がある。


また、ファイル管理が高度・高速になり、プログラム起動のコストが下がった。


こうなると、「ダブルクリックで閉じる」は面倒くさい操作だ。

これが、従来互換の「ダブルクリックで閉じる」も残したまま、新たな「閉じる」ボタンを増設した理由だと思われる。




NeXTstep …知っている人は少ないか。


Jobs が Apple をやめた後、新たに興した会社で作ったコンピューターの OS 。

一応、現在の MacOS X の元になっている。


この UI では、「右に閉じるボタン」になっている。


対抗して逆にしたのだろう、というのであれば、Windows よりも、NeXTstep の方が「対抗した」のだろう。

Jobs は、自分を追い出した Apple 社を見返してやろうという意気込みでこの OS を作ったのだし。


ちなみに、左端にもボタンが表示されるが、この内容・個数は状況によって変化する。

(windows や Mac でも、実のところ「3つボタン」の内容は状況で変化する。それと同じことだ)



Motif … UNIX 上で最初期に「統一された GUI デザイン」をやろうとしたツールキット。


Microsoft と IBM も協議に参加しており、かなり意見を出したようだ。

結果的に、Motif と Windows 3.0 と IBM の OS/2 は、似たインターフェイスを持っている。


IBM は UNIX も PC もやっていたし、その両方で使い勝手を統一したかったろうから、似ているのは必然。




最後の方は余談なのだけど、歴史を見ると、Mac も Windows も、「左上に閉じるボタン、右上に拡大ボタン」という、共通の GUI から始めている。


その後、それぞれの事情によりボタンが増えるが、基本的に Windows が先行し、Mac が後追いする形でボタンが増えていく。


Windows が「閉じる」を右側に増設したのはその後だが、先に書いたように互換性のために左にも残してある。

すでに、そのアイコンで閉じられることを知っている人は少ないと思うけど。




その後、MacOS X の登場時に、Mac の GUI は大きく変わる。

この時に、右にあったボタンも全部左に寄せられ、Windows と逆、という印象になった。


…そう考えると、「Windows が対抗して逆」なのではなく、「Mac が対抗して Windows と逆にした」のだね。

(NeXTstep で Mac の逆にした Jobs だからね…)



まぁ、実際のところは対抗心などではなく、「左上に閉じるボタン」という、初代から続く UI を残したまま、右と左に分散していた「ウィンドウを操作するボタン」を集中させた結果なのだと思うけど。




翌日追記


急に気になって、Apple Lisa OS を調べてみた。


Lisa は Mac の元になった機械で、のちには Mac と同じ OS を搭載できるようになっていたが、当初はオリジナルの OS を搭載していた。



Lisa では、ウィンドウ左上にプログラムを意味するアイコンが表示されており、そこをクリックするとウィンドウを閉じた。

この点では、今も続く Windows の「左上のアイコンクリックで閉じる」は、Lisa 由来かもしれない。



Lisa は Mac と違いマルチタスクだったが、Window を閉じると同時に、プログラムも終了しているようだ。

(Youtube で見ただけなので詳細はわからないが…)


最大化に相当するボタンはない。最小化も当然ない。

タイトルバーに存在するボタンは、左上のアイコンだけで、これが「閉じる」ボタンを兼ねる。



Mac になった時に、アイコンはなくなって、ただの四角い枠で「閉じる」を意味するボタンになったのだけど、これは Lisa に比べて、Mac は非常にメモリが少なかった、ということと関係するように思う。


そして、やはり最初は「閉じる」ボタンしかない。


「拡大」ボタンがついたのは System 3 からのようだが、System 2 以前の資料が少なすぎて確定できていない。




なんか、調べるほど Windows は「対抗して逆にした」どころか、Lisa / Mac の GUI の正当な後継のように思えてきた…




▲目次へ ⇒この記事のURL

別年同日の日記

02年 ピーナッツバター

11年 ポケモンな1日

12年 怒涛の1週間

12年 13~15日

12年 結婚10周年

12年 オムツはずれ

13年 追悼・富田倫生

14年 長男誕生日

15年 靖国神社参拝


申し訳ありませんが、現在意見投稿をできない状態にしています

iPhone SE 購入  2020-08-22 17:18:15  コンピュータ

▲目次へ ⇒この記事のURL

仕事のために「しかたなく」iPhone SE を購入しました。


…というのは、以前に MacBook Pro を購入した時の日記に書き出しを揃えてみた。


MacBook Pro は我が家の現役マシン単体では一番高価なものだが、やはり仕事でしか使ってない。

Safari での表示・動作確認が主な役割で、使うときは1日 30分くらい使うが、使わないときは2週間スリープしっぱなし、という感じ。

(2週間に1度くらいは使うが、その場合も5分で終わり、とか)



で、iPhone SE もそうしたマシンになる予定。

iPhone での表示確認を求められることがあったので…


ただ、こちらは Mac Safari の表示確認よりも頻度が低いはず。



▲目次へ ⇒この記事のURL

別年同日の日記

04年 大忙しです

13年 国立科学博物館

17年 夏の家族旅行 2017

17年 下田海中水族館

17年 とうてんぽーる

17年 アニマルキングダム・動物園エリア

17年 アニマルキングダム・遊園地エリア

17年 アニマルキングダム・2周目~帰路

19年 SVG うねうね


申し訳ありませんが、現在意見投稿をできない状態にしています

Lenovo Ideapad C340 購入  2020-08-22 17:58:23  コンピュータ

▲目次へ ⇒この記事のURL

Windows マシンを買い足した。

こちらは子供用。


5月に一度、子供用マシンを買おうとしたのだが、取りやめている

その後も探していて、やっと届いたところだ。




購入の一番大きな理由は、子供用の Chromebook が不調だから。


このマシン、元々 Chromebook の魅力が「安さ」だった時期に買ったので、購入時点で低いスペックのマシンだった。

低いマシンスペックでも満足な動作をしてくれるのが Chromebook の良さだった。



でも、その後 Chromebook の立ち位置は変わり、スマホのように気軽に起動できる、PC として作業が行いやすいマシン、になっている。

それに伴いマシンスペックも求められるようになり、高価格化している。


以前一度買って取りやめたマシンは、そんな中でも安かったから購入しようとしたのだが、安い理由は「日本仕様にしていなかったから」で、キーボードが US だった。

ローカライズ作業を省けば大量生産でコストが下がるのは事実だが、それはちょっと使いづらいので、返品となった。




その後も Chromebook を検討するが、それなりの値段になってしまう。

それなら、もう少し予算を上乗せして Windows マシンを購入したほうが、できることの幅が広がる。


子供用にはもう一台使っているマシンがあり、これはもともと妻が使っていたRaytrektab


特に長女が気に入っていて、絵を描くのに使っている。

(長女は小学生のころから絵を描くのが好きだったが、中学になっていわゆる漫研に入った)


じゃぁ、さらに予算を上乗せして、ペンタブとしても使える 2in1 マシンにしようか…



というわけで、Ideapad C340。

税込み6万円弱。子供に使わせるにはちょっと高価だが、勉強への活用も考えると、これくらいのものは買っておいてよいだろう。


…といっても、今のところ使っているのはもっぱら次女。

今まで次女が主に使っていた DELL Inspiron 15 N5010 では「ペンでお絵かき」はできなかったので、喜んでいる。


というか、このマシンはさすがに 10年前のもので、物理的にも動作的にも重い。

Chromebook が動かなくなったので、暫定的に使ってはいたのだけど。




少し余談に入る。


次女はキーボード付きマシンを使うことが多いので、ワープロ使ったりするのも楽しいらしく、いつの間にかお気に入りの歌の歌詞カードを作っていたりする。


一方、長女はキーボード慣れしていなかった。



それが、夏休みの宿題で読書感想文を原稿用紙5枚書かなくてはならなくなった。

長女は文章を書くのは嫌いではないし、親から見ても結構うまい文章を書くのだけど、今まで書いたことがあるのは、せいぜい原稿用紙2枚。


どうすればいいのか途方に暮れていた。



そこで、慣れていないかもしれないが、ワープロの活用を勧める。

今回の購入マシンではなく Inspiron を使ったのだけど、「文章を頭から考える」のではなく、読書感想文として、思ったことをメモでもいいからどんどん書き出してみな、とつたえる。


僕としては箇条書きでもどんどん書いていく、というのを勧めたのだけど、慣れていないので難しい。

結局、ある程度まとまった文章の断片がいくつかできて、その間のつながりが難しいとか、この話をどうまとめたらいいのか、とか、そういう形になった。


読書感想文って、「感想」を引き出すまでが一番大変なのだけど、ワープロだと何度でも書き直せる気楽さで、結構いろいろと引き出せていた。


こまでくれば後はテクニックの問題。


それぞれの文章はどういう気持ちで出てきたものなのか、その間にどう関連性があるのか、などを本人に聞いてみると、書いていないことを説明し始めた。


つまり、その言葉が足りないからうまく繋がらないんだ。

そこを補わないといけない。


他にも、長女の場合、文章が少し長すぎて伝わりにくい部分があったので、できるだけ短く区切ることを提案。

短く区切って並び替えるだけでも、文章はずっと伝わりやすくなることがある。



大体できたところで、書式設定をして、20文字*20行を1ページにする。

これで、5ページになるように文章量を調整。



慣れないワープロ作業は大変だったようだが、本人も「紙に向かって書いていたらこんなの書けなかった」という、満足いく仕上がりとなった。


…で、学校の規定で、原稿用紙に鉛筆で書かないといけないので、この後地獄のような写経作業があったのだけど。


(これが一番大変だったようだ。もっとも、ワープロを使わない場合は、適当な紙にさんざん書いたうえで、さらに清書する作業があるので、ワープロの方がやはり作業量は少ないだろう)



先に書いたように、「勉強にも活用」というのは、こういう作業も含む。

調べ学習程度なら WEB ブラウザが使えればいいし、極論すればスマホで十分かもしれない。


でも、ここは妥協したくないところなので、キーボード付きのマシンにこだわっている。



#もちろん、タブレットに Bluetooth キーボードでも構わない。

 僕の場合は、子供に気軽に使って欲しいので、多少高くてもややこしい設定のいらないマシンを買っているだけ。




今回購入した Ideapad は、申し込んだのは7月末。

この時点で「お届けは1か月以内」だった。


その後、「人気があるので出荷が遅れ、9月頭の予定です」とメールが届き、まぁ仕方がないだろうと思っていたら、8月の半ばに「出荷しました」連絡が来た。

届いたのは、5日ほど前。



7月末に申し込んだのは、コロナウィルスの感染者数が急に増え始めたため。

このまま再度学校がネット授業になった場合に、子供の PC の数が間に合わん、と思って購入。


結局そうした事態には至ってないのだけど、出荷が間に合わないほどの人気になっていたのは、同じことを考える人が多かったのでしょうね。



▲目次へ ⇒この記事のURL

別年同日の日記

04年 大忙しです

13年 国立科学博物館

17年 夏の家族旅行 2017

17年 下田海中水族館

17年 とうてんぽーる

17年 アニマルキングダム・動物園エリア

17年 アニマルキングダム・遊園地エリア

17年 アニマルキングダム・2周目~帰路

19年 SVG うねうね


申し訳ありませんが、現在意見投稿をできない状態にしています


戻る
トップページへ

-- share --

0000

-- follow --




- Reverse Link -