2017年11月7日火曜日

Shell scriptで計算する際の注意

Raspberry Pi 3 Model BでLED照明をPWM制御するshell scriptを書く為にちょっとした計算が必要になった。

このscriptに与えるのは0% (消灯)〜100% (フルパワー)の数値 (0-100)で、これを実際のPWM制御に使っている0-255に変換したい。つまり、percentage → 実際の数値の変換である。この時、percentageもPWMの数値も整数とする。

Shell scriptで計算するには主に次の3つの選択肢がある:

* expr
* bash/zshなどのbuiltin → $(( EXPR )) ※shebang注意 (/bin/shだと使えなかったりする)
* bc

exprは整数演算しかできないし、shell builtinは整数への丸め方が分からないのでbcを使っていたのだが、最終的には「小数点以下の切り捨てを回避できればどれでもok」だと分かった。

うまくいったやりかた


例題: 255の76%は193.8 (193)

expr

 % expr 76 \* 255 \/ 100
 193

exprに与える式はescapeしてある (*とか/とか)

shell builtin

zshで実験した:

 % echo $((76 * 255 / 100))
 193

exprと違いescapeする必要はない。

bc

 % echo "76 * 255 / 100" | bc
 193

最初試した間違っているやりかた


percentage = A / B * 100

という式から:

A = percentage / 100 * B

と変形してそのままimplementすると、percentage / 100の結果が小数点以下の数値になり、小数点以下の演算を扱えない場合に切り捨てられて0になる。例えばbcで:

 % echo "scale=0; 3 / 255 * 100" | bc -l
 0

となるのはこのため。無論、3 / 255 * 100 = 1.1765... なので (数学的には) この結果はおかしい (少なくとも意図した結果ではない)。

bcの場合はexprと違って小数点以下の数も扱えるのだが、この場合はscale=0の効果で 3 / 255 = 0.0039...が0になるので、その後から幾ら数を掛けようと0にしかならない訳だ。

そこで、乗算と除算は (実数の範囲では) 順序を変えても計算結果が変わらない性質を利用する。

A = percentage * B / 100

つまり、3 * 100 = 300 を計算してから 255で割れば、無理なく整数部分を取り出せる:

 % echo "scale=0; 3 * 100 / 255" | bc -l
 1

これが望んだ結果である。

蛇足


乗算の順序に拘るような学校教育を真に受けた子供達が、結果の同じ演算の順序を変えることを思い付かずにこの手の問題を解決できなかった、なんて理由でプログラミング教育や実際のコーディングに悪影響が出なければ良いなとつくづく思う。

まあ、大抵のプログラミング言語は小数点以下も扱えるし問題ないか……。

2017年11月6日月曜日

KeySnail userの行き着く先: Waterfox

Firefox 57が近々releaseされる (2017-11-14)が、それに伴いlegacyとされているaddonが使えなくなる。

FirefoxをEmacs風のkeybindで操作できるKeySnailもその一つである (ちなみにVi (Vim)風に操作できるVimperatorも)。

前のentryでこのことについて書いたが、対策はざっくり:

* ESRで当座を凌ぐ
* WaterfoxやPale Moonに移行してKeysnailを使い続ける
* 似た機能を提供するWebExtensions対応のものに乗り換える

である。

取り敢えず、現在使っているaddonを変える必要がないであろうWaterfoxを導入して試してみた。

Install


環境


* Intel Core i7 7600K
* Linux kernel 4.14rc6 (rc7でtroubleが発生し戻している、ちなみに最新はrc8)
* Debian Sid (amd64)

Prebuilt binaryからのinstall


手軽だし早いので特に理由がない限りこちらを勧める。

* Binaryを落として適当なdirectoryに展開する

cf. [Waterfox - The free, open and private browser](https://www.waterfoxproject.org/)

Source codeからのinstall


* 本家Fxはhg (mercurial)で管理されているが、Waterfoxはgitで管理されている
* git clone https://github.com/MrAlex94/Waterfox.git ※sizeが大きいのでshallow cloneが良いかもしれない
* Build systemはFxと同じなので./machを使う
* .mozconfigを眺めてみた所、default compiler (CC)はclangだった。そのままでも良かったがgccでbuildするよう書き換えた

うまくいかなかった点


* .mozconfigのprocessor数から並列buildの数を決める部分でコケた
* Build時のCPU使用率などをmonitorするpython scriptがコケた

それぞれ適当に対策した結果buildが通った。

./mach build → ./mach packageでtar.bz2を生成し、それを適当なdirectory (~/.waterfox/とか)に展開し、~/bin/waterfoxあたりにsymlinkを張っておくと便利。

既存のFxのprofileをimportする


* waterfox -ProfileManagerでprofile managerを開く
* 適当な名前 (または以前と同じ名前)でprofileを作る
* 一度waterfoxを終了する
* ~/.waterfox/以下にprofile directoryがあるので、copy元の~/.mozilla/firefox/以下あたりからcp -Rとかでcopyする eg. cp -R -f ~/.mozilla/firefox/default.XXXXXXX ~/.waterfox/default.YYYYYYY

cf.

* [古いプロファイルから必要な情報を復旧する | Firefox ヘルプ](https://support.mozilla.org/ja/kb/recovering-important-data-from-an-old-profile)
* [プロファイル | Firefox ヘルプ](https://support.mozilla.org/ja/kb/profiles-where-firefox-stores-user-data#w_firefox-acioaoaoaecucgciaaacceciaececaacdoacaaaoaeag)

動作確認


* waterfox -ProfileManager或いはwaterfox -P <PROFILE>でprofileを指定してinvokeする
* うまくいっていればbookmarkとかhistoryとかextension (addon)とかが引き継がれているはず

結果


* bookmarkやhistory、passwordなどが引き継がれていた
* addonもそのまま利用可能だった
* Flash (Pepper Flash)も動いた

思っていたよりもWaterfoxへの移行は楽に完了した。Sourceからのbuildではなく、prebuilt binaryをdownloadして展開すればもっと早く終わる。

KeySnailはもちろん、Tab GroupsとかFireGestures、Down ThemAll!、Tab Mix Plus、Tile Viewといったlegacyなaddonsも確認した範囲では正常に動作していた。既存のaddonsが必須な人はWaterfoxへの移行を検討する価値があると思う。

Firefox 57 (aka. Firefox Quantum)がやって来る

Mozilla Firefox 57 (Firefox Quantum)のreleaseが間近に迫っている (2017-11-14)。

既にdeprecatedとされている従来のadd-on (extension)が使えなくなるため、特に以前からのuserは大きな環境の変更を迫られる。

対策は大きく分けて次の通り:

* Firefox ESR 52を使って暫く環境を維持 (〜2018-06-26)
* WebExtensionsに対応した代替を見付けて新しい環境へ移行
* Firefoxから別のweb browserに乗り換える (Firefox系列 / 非Firefox系列)

ESRで暫く繋ぐ


主に企業user向けに提供されているESR版は、新機能の追加や抜本的な変更が (次のreleaseまでは)行われない。最新版であるESR 52は2018-06-26までsecurity updateの対応がなされる。

cf. <https://www.mozilla.jp/business/#esr>

Pros


* Firefox 52をbaseにしているので従来のadd-onも問題なく動く (はず)
* 移行の手間がそれほど掛からない
* 頻繁なupdateから開放される

Cons


* あくまで対症療法であり、何れは移行先を見付けなければならない

WebExtensionsの世界へ移行


今使っているadd-onやthemeなどの必要性や移行先を検討し、新しい環境へと移行する。

Addonやthemeに余りこだわりがないとか、使い始めたばかりで移行すべきものがないとか、customizeを全く/ほとんどしないuserに向いている。

Pros


* 根本的な対策であり今後暫くは継続的に使える環境が構築できる (はず)
* 改良されたFirefoxのuser experienceを満喫できる

Cons


* 様々にcustomizeしていたuserほど手間も時間も掛かる
* 便利に使っていたaddonやお気に入りのthemeの代替が存在しない

同系統のBrowserへ乗り換え


例えば、以下はFirefoxからforkしたbrowsersである:

* Waterfox (cf. <https://www.waterfoxproject.org/>)
* Pale Moon (cf. <https://www.palemoon.org/>)

XULやXPCOMといった技術が引き継がれるので「深い所まで自由にcustomizeできてこそFirefox」という人には向いている。

Pros


* (おそらく) 移行にかかる手間は少なくて済む
* 現在使っているaddonやthemeなどの資産をそのまま使える
* 見た目や操作体系が同じ

Cons


* 枯れた技術が保守されている状況なので大幅な性能の改善は見込めない
* Browserそのものshareが少ない (websiteが正式に対応していなかったりする可能性が高い)

全く別のBrowserへ乗り換え


現在使っているaddonやら何やらの代替が見付からない場合、いっそ全く別のbrowserに乗り換えてもかかる手間は変わらないかもしれない。

* Google Chrome (或いはChromium)
* Microsoft Edge (Microsoft Windowsのみ)
* Apple Safari (Apple macOS, iOSのみ)
* Opera
* Vivaldi
* Brave
* etc, etc ...

特にChromeはuser数が多くextensionsも充実している (と考えられる)。

Pros


* BrowserはFirefoxだけではないと分かる
* 真っ新な環境から始められる

Cons


* 検討すべき候補がありすぎて選ぶのに手間取る
* これまでの操作体系とかなり異なる場合慣れに時間がかかる
* 移行に手間がかかる (かもしれない)