Joplinを排除してノートアプリを完全にZimに移行したあと、うっかり その修正・改良を始めてしまい※、随分手こずったものの(2週間くらい掛かった!)かなり良くなって、概ね満足できるレベルになった。

※いろいろムカつく問題があったのだが、他にないので変更・修正や代替策などで数年間我慢して使っていた。

そして、僕の改良・改造版はノートのフォーマット(タグ)は違うし、機能・動作は かなり違うし、プログラムの構造も少し変更してオリジナルとは全く違うと言っても いいほどなので、名前を"Zimb"(Butty's modified Zim または Butty's note taking app. (Modified version of Zim))に変えた(例によって(夜中に)思い付いたw)。

オリジナルを尊重して元の名前を残し、読みも同じに なりそうなものにした。

なんかイメージの良くなさそうな南のほうの国を連想するが、まあ良しとするw

作業を始めた切っ掛け

Joplinの作業が終わり、延々と放置して来たZimのTODO(修正・改良)に着手すべきだけど、やっぱり面倒な気分でも あった(やらなくても とりあえず使えるし・・・)。ただ、以下のような ちょっと切実なことが切っ掛けになったように思う。

  • ベースを最新版※にしたくなった(V.0.74.2 → 0.75.2)。: 以前からやりたかったが、面倒なので放置していた。
    • どうせ変更(修正・改良)するなら、最新版をベースにしたほうが良いので。
    • ※作者は開発を止めた訳ではないようで、思い出したように(年に数回)更新している。ただ、機能や動作は ほとんど変わっていない感じだ。
  • Zimのノートのgitリポジトリ(バージョン管理プラグインが使う)が大きくなってしまった(500MB以上)。: Joplinの画像が多かった。ノート以外はgitに入れる必要は ないのに、馬鹿みたいに全部入れていた。
    • ある時、バックアップのサイズが大きいファイルが目に止まって気付いた。
    • 余計なファイルを削除してgitリポジトリを小さくするために、(調べて見付かった方法がうまく行かなかったので、)BFGというプログラムを使った。結構簡単で良かった。
    • 作業中に気付いたが、ZimのノートのDB(SQLite)も大きくなってしまった。: 上と同じ原因で、ご丁寧にもノートでないファイルもスキャンしてDBに登録・更新していた。
      • それでノートのエクスポートやプログラムの終了が遅くなって居た(多数(1万個以上)のファイルのインデックス処理をするため)。
  • ZimのPage indexプラグインで鬱陶しいURL(link placeholder)を消したい。
    • URLをノートにペーストすると、左サイドバーのノート一覧に それ由来らしき(エンコード? ダイジェスト?: 分からないので部分的に隠した)記号の名前のページが出て増えて本当のノート名が見えにくくなって、すごく不便だった。
    • 以前削除しても復活したので、諦めていた。

ベースを最新版に

手間は掛かったが、意外にすんなりできた(最新版までの変更が少ないということ)。比較とマージをGUIで手軽にしたかったので※、Linuxで使えるものを探したら いくつかあったもののどれも満足できなかったが、一番良かったMeldにした。

※昔はWinMergeを使ったのを思い出す。

Zimの修正内容

主なものを以下に列挙する。

  • 2重表示の問題(ページの再描画が おかしいことがある)
    • 現象
      • 大きいノートの後半辺りに行を挿入したりすると、その前後の行が微妙に ずれて2重に表示されることがある。
      • 一旦 別のアプリのウインドウをアクティブにしてZimに戻ると直る。 → 今まではそれで しのいでいた。
        • ↑のためにキャプチャを取るのが難しく、提示できない。
    • 原因: プログラムの処理が不適切(ページ描画処理手順が悪い(推測)のと その回避のための"HACK"処理(下を参照)が良くない)。
    • 参考
      • これを解決できたので、プログラム中の謎の処理"_hack_on_inserted_tree()"(zim/gui/pageview/__init__.py, 以下、"HACK")を不要に出来た。
      • この問題と下のノート切り替え時のカーソル位置の復元は関連している。
        • カーソル位置の復元などのためにHACKがあるのだが、その処理が不適切なために2重表示が起こっていた。
        • そもそも、ZimのGTKの使い方が今一つなためにページ描画が遅くなり、HACKがないとスクロールできない(→ カーソル位置が復元できない)問題が起こっていたと推測する。
      • (9/18 14:59) LibreOffice Calcでも起こった(以前からあったのを忘れて居た)ので、GTK全般で起こりうる問題のようだ。ただ、いつも・どのアプリでも起こる訳でないので、起こりやすい条件(描画の仕方? グラフィックデバイス関係?)があるのだろう。
    • 対処: ページ描画手順を真っ当と思われるものに変更し、HACKを不要にした。 (詳細は実装メモを参照)
  • (2重表示の問題が起こらないようにHACKを無効にした構成では、)ノート切り替え時にカーソル位置が復元できない。
    • 現象: 上のHACKを有効にしないと、ノート切り替え時にカーソル位置が復元できない。
      • ただ、HACKが有効でも、大きいノートでは復元できないことが多い。
    • 原因: プログラムの処理が不適切(ページ描画処理手順が悪い(推測))
    • 対処: ページ描画手順の変更。
  • 長い行を綺麗にラップ(折り返し)できず、横スクロールバーが出ることがある。
    • 現象: 長い行は適切にラップするはずだが、横スクロールバーが出るうえにページが左にずれて行の先頭が隠れてしまうことがある。
      • なぜかHomeキーではカーソルを戻せないので、すぐには行の先頭が見えず大変不便。
    • 原因: 不明。
      • Zimの問題なのかGTKの(設定の)問題※なのか不明
        • ※他のアプリでも似たような現象が起こることがある。
    • 暫定対処: ページのマージン(特に右マージン)の調整
      • かなり大き目(例: ページ幅約800pxに対し、50px)に右マージンを取った。
      • 試行錯誤のため、マージンなどを設定で容易に調整できるようにした。
    • 参考: これでもスクロールバーが出ることがあるので、完全には対処できていない。
      • スクロールバーが出るのは、大きな画像がある他にVerbatim(文字を そのまま出す書式)の長いブロックが関係していそうだ。あと、日本語は単語の区切りの空白がないので、そもそもラップしにくいのかも知れない。
      • このブログの表示を見て思ったが、単語間(駄目な時は文字)で切るのに加えて、字の間隔を微妙に伸縮させて調整できると随分良くなりそうだが、GTKでできるのだろうか?
        • ただ、それも破綻する(日本語の文字が飛び石になってしまう)ことがあるので良し悪しだ。。。
  • Zimアプリ(GUIプログラム)を閉じて終了させてもプロセスが残って居ることがある。
    • 現象: Zimのウインドウを閉じてもプロセスが終了しない。
      • 修正・改良後の確認時にはkillコマンドで強制終了する必要があって(そうしないと残ったプロセスが動くので、変更点の確認ができない)、大変不便だった。
    • 原因: バックグラウンドで実行しているインデックス処理が終わらない。 (上の「切っ掛け」を参照)
      • ノートのディレクトリにあるすべてのファイル(1万個以上)をインデックスするため、時間が掛かっていた。
    • 対処: ノートのファイルだけをインデックスするようにした。
      • インデックス対象と除外するファイル・ディレクトリ名のパターン(正規表現)や種類(sym-linkを除外するか)を設定で指定できるようにした。

Zimの改良内容

主なものを以下に列挙する。

  • タグの中に使えない文字がある。: 例: VERBATIM(文字をそのまま出す書式)なのに ' が使えない。
    • VERBATIMは、タグが '' で本来の文と競合するようなので、書式のタグを変更した。
      • Zimを使い始めた時の変更(下も参照)と同様に、タグの文字列を、本来の文と競合することが少なそうなものにした。また、タグは2文字構成だが、開きと閉じそれぞれの先頭と最後の文字を、一般には使わない「変な文字」にした。
        • 参考: Zimを使い始めた時に、かなり不便だったので(その他の"__"の件を参照)次のタグを変更した。: EMPHASIS(斜体), MARK(下線)
    • 同様に、次のタグの書式を変えた。: VERBATIM, STRONG(太字), STRIKE(取り消し), SUBSCRIPT(下付き), SUPERSCRIPT(上付き)
    • タグを変更すると以前のノートを修正(タグを変換)する必要がある※が、読み込みは新旧両方に対応し、書き込みは新しい書式にすることで、変換を不要(自動変換)にした。
      • ※それで追加のタグ変更を保留していたが、今回は少しスキルが上がって上のような うまい方法ができた。
  • 埋め込み画像サイズの自動調整
    • 画像をインデントした場合でもページ幅を超えないように、自動で縮小するようにした。: 上述の横スクロールバーをなるべく出さないため。
      • デフォルトや最小サイズは設定で変更できるようにした。
      • そのため、画像が多いノートの描画が遅い。
        • → 思い付きだが、ノートをビューに表示する時に初めて、実際に表示される画像を読み込めば良い気がする(webのlazy loadingのイメージ)。ただ、それがGTKで可能なのかは不明だ。
          • 例えば、TextBufferの中にコールバックを設定とかできるのだろうか? あとは本当に そういう属性があるか。: まあ、忘れたほうが良いw
  • URLをペーストした時、自動でクリッカブルリンクにしないようにした。
    • 上述のURL由来の変なノートができるのを防ぐため。
    • 自動でリンクになるのは便利だが、不意にクリックすると勝手にブラウザでアクセスするため、神経を遣って却って不便なので無効にした。
      • 手動操作でリンクにすることは できるので、問題ない。
  • ウインドウなどの設定ファイルなどの位置を変えた。
    • オリジナルではノートのインデックスのDBとともにキャッシュディレクトリ(~/.cache/zim)に入っているが、キャッシュは「いつ消しても大きな問題は起こらない」と思わせて適切でないので、(いい場所が思いつかなかったものの)~/.local/share/zimにした。
      • 本来はウインドウなどの設定は~/.configが良いが、なぜかDBも一緒に保存されて分割が容易でないので そうした。
  • MDでのエクスポート時の上下付き書式を変更した。
    • これまではJoplinが対応している形式(^, ~)だったが、スマフォのビューアをObsidianにしたのでGFMの形式(HTML, <sup>, <sub>)で出すようにした。
  • キャレットを点滅しないようにした。: イライラする(までは行かないが、「うるさい」)ので。
    • 点滅を設定する方法を調べたが、プログラムからはできないようなので、GTKの設定ファイル(~/.config/gtk-3.0/settings.ini)に以下のように書いた。※
[Settings]
gtk-cursor-blink=0
      • ※そのため、他のアプリも同じ設定になるが、そもそも点滅が嫌なので問題はない。
    • それに伴い、キャレットの色や太さを調整した
      • キャレットが点滅せず細いと、黒はもちろん 色が付いていても、ページ切り替え後に どこにあるか分からないことがあるため。
      • また、太過ぎると文字の一部を隠してしまうことがあるので、太さ(アスペクト比)を微調整した。
        • 太さは今一つ調整の自由度(ステップ)が少ない感じだ。
        • また、アスペクト比の設定のため、行が高い場合(例: 画像のある行)はキャレットが巨大になってしまう。この回避方法は まだ分からない。
    • 変更する方法を調べたが、プログラムからはできないようなので、GTKのCSSファイル(~/.config/gtk-3.0/gtk.css)に以下のように書いた。※
* {
  caret-color: #812a2f;
  -GtkWidget-cursor-aspect-ratio: 0.12;
}
      • ※キャレットの点滅と同様に他のアプリも同じ設定になるが、このブログのヘッダの色に近く、悪くない感じの色なので大きな問題はない。

実装メモなど

A. 2重表示問題の対処・描画処理手順の改良

僕はGTKに詳しくないが、Zimのプログラムを調べて分かったことと推測したことの概略を書く。

  • オリジナルのZimは、以下の順序でページ(ノート)を描画している。
    1. ページ(ノート)全体(ノートのテキストと埋め込まれている画像全部)を読み込んで解釈し、バッファ(TextBuffer)に描画オブジェクトを作り上げる。
    2. 出来上がったバッファをビュー(TextView)に登録する。 → GTKの描画処理が始まる(全体を一気に描く)。
    3. [HACK処理]
      1. GTKの処理がアイドルになるまで待つ(GLib.idle_add(hack関数))。
      2. hack関数: 指定時間待ってからスクロールする(GLib.timeout_add(タイムアウト, スクロール関数))。
        • 本来はアイドルになるまで待てば充分なはずだが、うまく行かなかったのか、指定時間待ってからスクロールしている。
          • 実際、タイムアウトが短いと充分にスクロールしない。
      3. スクロール関数: カーソル位置を復元するため、ビューをスクロールさせる。
  • GTKで一気に表示処理をするため、どういう理由かは分からないが、上述のスクロールが行われない問題が起こる。
  • それを回避するためにHACK処理をしているのだろうが、2重表示の問題が起こる。
    • 調べた限りでは、(理解不能なものの)HACK処理自体は悪くないが、複数の(余計な)ところから実行するのが良くないようだ。

ただ、他のアプリで 上のような問題(スクロールしない, 2重表示)が起こっているのを見たことがないし、検索しても出て来なかった。※

※スクロールが起こらない問題に関しては あったが、Zimは ちゃんとスクロールできるはずの方法で実行していた。

そこで、一気に描画するのが良くないと考え、順次描画するように、以下のような順序にした。

  1. 空のバッファ(TextBuffer)をビュー(TextView)に登録する。
  2. ページ(ノート)を読み込み、順次バッファ(TextBuffer)に描画オブジェクトを作り上げる。 → GTKは順次描画処理を するはず。
  3. GTKの処理がアイドルになるまで待つ(GLib.idle_add(スクロール関数, カーソル位置))。
    • これはオリジナルのHACK処理にヒントを得た(上を参照)。
  4. スクロール関数: カーソル位置を復元するため、ビューをスクロールさせる。

駄目元でやったのだが、意外にうまく行った。まだ1日くらいしか試していないが、今までに1度2重表示が起こった(これが気になるが・・・)ものの、カーソル位置は常に復帰できて かなり改善できたし、謎のHACK処理が不要になった。

ただ、変更前はページが順次描画される(例: ノートの先頭から描画されるのが見える)ようになると思って居たが、そうではなく、どういう訳かビューは ずっと空のままで、最後に一気に全体(ビューのうち見える部分)が表示される。

調べていないが、もしかすると、表示に関する もう一個のPageViewというwidget(VBox)とTextViewの関係があるのかも知れない。上述のTextViewとTextBufferのように、最後にTextViewをPageViewに登録しているのだろうか。 ← プログラムを見てみたが、そうではないようだ。TextViewはPageViewの生成時に設定している。

(21:55) 最後に一気に表示されるのが気になってプログラムをチェックしたら想定と違っていて、上の手順の1の空のバッファ(TextBuffer)をビュー(TextView)に登録していなかった。そのために一気に表示されたようだ。

ということは、最初の(抜けのあった)修正でも うまく行ったポイントは何だったのか分からなくなった。: 結局、オリジナルのHACK処理と その実行の仕方が悪かった(「素直」でなかった?)のか。: また あとで考えたい。

それで上の手順になるように修正したら、画像の多いノートでの描画開始までの待ち時間は相変わらず長いものの、描画途中の状態が ちょっと見えてから復元されるべきカーソル位置にスクロールするようになり、想定に合うようになった。

この辺りには まだバグがありそうだ・・・

B. 特定のキーが取れない

動作確認をしていて気付いたのだが、なぜかショートカットのCtrl+5がZimに届かなかった(妙なことに、Ctrl+4まではOKだった)。更に、Alt(Shiftなし)は全滅だった。いろいろ調べたら、FcitxがCtrl+5を取っていた。。。※ AltもFcitxが怪しい(どうしても解決できなかった)。

※なんで そういうテキトーな割り当てをするか不明だが、まあ、そういうプログラムなので仕方ない。他にもムカつくことはあるが、他にないので我慢+可能な修正をして使って居る。

(9/14 19:15) 取れないキーは他にもあった。: Ctrl+0やCtrl+. が取れないことに気付いた。前者は(僕がPythonとGTKに詳しくないため、)プログラムの誤りなのか他に原因があるのか分からないが、プログラムを修正して使えるようにした。 ← その後、また駄目になって居た。全く謎だ。 (19:44) ← その後、Zimを起動するディレクトリによって動作が変わることが分かった。 (20:39)

Zimの開発ディレクトリで起動した場合、その下位に そのキーの機能(Remove heading)を含むメニューバー定義ファイル(menubar.xml)が あってキーを取得するが、そうでないディレクトリからは古い版の定義ファイルしか参照できず、キーが無効になった(この機能は最新版で追加されたようだ)。

定義ファイルにはキー割り当ては書いてないけど なぜか関係しているので、大変分かりにくい。また、新しい定義ファイルでは下の変更は不要だった。

具体的には、下のショートカットキーの定義らしき行で、オリジナルには"accelerator="がないのだが、それを他に合わせて入れたら取れるようになった。ただ、別のキーで それがないものも動いているので、何だか分からない。

@action(_('_Remove Heading'), accelerator='<Primary>7', menuhints='edit')

後者は ひどく、FcitxだけでなくGTKも取っていた。GTKでは絵文字一覧(Emoji chooser)が出てしまう。調べても、設定で出ないようにする方法が分からない(プログラムでの方法は あったが、これは全体的に無効に変更したい)・・・ 杜撰なソフトは多いが、GTKは ひどい。使うための資料も機能も不足している。

残件

まだ結構あり、以下の順序で対応したいと思う(が、疲れたし、充分問題なく使えて居るので面倒だ・・・ → また数年後?)。"[Fix]"は修正、その他は改良である。

  1. ノートのsuffixの変更
    • 今は なぜか"txt"で、普通のテキストファイルと区別できず不便なので変えたい。
  2. 書式タグと本来の文を競合しにくくする(残り)
    • 次が残って居る。: IMAGE(埋め込み画像), LINK(リンク・埋め込みファイル), VERBATIM_BLOCK(複数行のVerbatim), OBJECT(不明), HEADING(見出し), TABLE(テーブル), LINE(水平線)
      • 箇条書きの*と同様に、そのままでも良さそうなものがあるので、良く考える必要がある。
  3. クリップボードをplain textとしてペーストする機能の追加, ペーストするフォーマットの順位設定
    • ([Fix] ファイルマネージャ(Thunar)からのファイルパスのペーストがリンクになる。)
    • 今はxselコマンドを使った外部プログラムで実現している。
  4. 日付の挿入(Ctrl+D)時、カーソル(上下)で書式を選べるようにする。
    • 今はマウスでしか選択できない。
  5. [Fix] 日英混在の場合(?)、ダブルクリックでの単語の選択が おかしいことがある。
    • GTKの問題・設定かも知れない。
  6. [Fix] カーソル(キャレット)の見栄え
    • もう少しなんとかできる?
  7. [Fix] 書式など(例: 箇条書き)のプルダウンメニューの展開が なぜか遅い。
  8. ツールバーの箇条書き, 番号付きリスト(, チェックボックス, 見出し)の各要素を独立させて横に並べる。
    • 煩雑になりそうなので、要検討。

また、以下は対応困難か実害が少ないので、非対応か保留にしようと思っている。

  • 長い行を完全にはラップできず、横スクロールバーが出ることがある。: 頻繁に起こるなら対処する。
  • ノート中に画像が多いとメモリを食うのは仕方ないが、適宜解放できるとうれしい。
    • 動作を見ると解放していない訳ではないので、Pythonのメモリ管理の問題か、Pythonが解放してもOSが「引き取っていない」のかも知れない(調べたら、良くあるようだ)。
  • アプリ終了時に全部の子プロセスを止める。

その他

ここまで読めば分かると思うが、オリジナルのZimは使いものにならないと断言できる(「敢えて言おう、〇〇であると!」レベル)。良く作者は気付かないものだ。そういうのは気にしない人なのか、自分では余り使ってないのか??: ベースが使えるものなので怒りはしないが、プログラムは なかなか几帳面に書かれているだけに理解不能だ。

  • 例えば、ZimはPythonで書かれているから、作者は"__init__"のような文字列をZimのノートにペーストしそうだが、ペーストの直後にVerbatimの書式に設定しない限り、下線の書式("init")に変換されてしまう。
    • 同様に、Pythonのdocstring('''...''')をペーストしたら、コードブロックに変換されてしまう。
  • 結局、普通に書いて そのままだと情報が変わってしまい(上の例では__'''が失われる)、ノートアプリとしては失格だ。
    • そういうのを書くたびに、漏れなくコードの書式に設定しているのだろうか。気にしないのだろうか? それでも、いくらなんでも__は不便だと思う。

感覚や思想の違いだと思うが、Zimは余計(邪魔)な機能が多い割に、基本的なことが欠けている。だから、随分可能性があるのにユーザーが増えないのではないか。

 

書いたあとでの追加

A. メモリ使用量についての調査・検討 (9/13 15:36)

上に書いたように、Zimがノート中の画像が多いとメモリを食い、しかも増え続けるのが気に入らなかったので少し調べてみた。すると、いろいろなことが分かった。

まず、Zimには意外にもページキャッシュがあることが分かった。どうやらページの表示イメージ(≒ TextBuffer)をそのまま格納しているようで、ページを2回目以降に開く場合は すごく高速になる。※ それは良いが、ページがキャッシュに残って居るうちはメモリ使用量は減らない。しかも、どうやら無限のページ数をキャッシュするようなので、メモリ使用量が増え続けるのが納得できた。

※今までは、僕がZimを使い始めた時にした改造が障害になって高速にならないことが多かった感じだが、この調査のために それを無効にしたら、カイカン的な速さになった。: 画像が多いノートでも一瞬で出る! (その代わり、メモリ・・・)

そこで、キャッシュのエントリ数(保持するページ数)を制限してみた(例: 10)。数が上限に達した場合には、(とりあえず、)最も過去に参照したものを削除するようにした(LRU)。が、それでも減らない感じだった。

更に調べると、ZimはPythonで書かれているため、基本的には、使われなくなった(= 他から参照さなくなった)メモリはGC(ガベージコレクション)で自動的に解放されるが、相互・循環参照※されていると解放できないことがあるそうだ。 (→ 参照: 大雑把にしか読んでないが、随分参考になった。)

※相互・循環参照の例を以下に書く。

    • 相互参照: 2つ(以上)のオブジェクトの間で参照し合っている。: A → B → A
      • 参照が片方向だけなら問題ない。
    • 循環参照: 自分で自分を参照している。: A ⇔ A

プログラムを調べてみると、確かに、テキストバッファ(TextBufferクラス)には他のクラス(例: その上位のTextView)のオフジェクトと相互に参照し合っているメンバがあった。そのためにページを切り替えても解放されない可能性がある。

相互参照はオリジナルのプログラムでもあったが、僕が追加した部分が多かった。上のようなことを知らずに、「ちょっと」上位クラスのメンバを参照したくて、テキトーに追加したためである。

そこで、とりあえず、ページをキャッシュから削除する時には もう誰も参照しない時だろうから参照関係を切っても良い(プログラムの動作が破綻しない)と考え、そのような処理※を追加したところ、概ね期待どおりの動作となった。

※具体的には、A → B → Aという参照関係がある場合、BのメンバのA(へのポインタ)にNoneを代入してB → Aを切った。

残念ながらメモリ使用量が減ることはないが、増え続けることもない。: キャッシュ内のノートのサイズの合計が それまでの最大値以内である限りは増えることがないので、プログラム(Python)内でメモリをやり繰り(再利用)できていると考えられる。

減らない理由を想像すると、(上述のように、)Pythonが解放してもOSが受け取らない のではないかと思うが、他に、まだ参照を切るのが甘い可能性もある。

というのは、どこで参照しているのか分からないが、キャッシュから削除する時の参照カウントが70近いからだ。どうしてそんなに参照が増えるのかは謎である。

(9/14 12:39) 参照カウントが随分多いのが気になったので参照元を調べたところ、ページの参照の大半はファイルタイプの定義(例: 'image/png')からのようだった。今回はプログラムは見ていないため、なぜそんなものが他のオブジェクトを参照しているかは不明だが、そういう実態だ。そして、メモリ解放の障害となる相互参照は、上述の「僕が追加した部分」だった。

(9/14 16:33) その後 更に試したところ、キャッシュから古いエントリ(ページ)を削除したあとで強制的にGCを実行すれば、キャッシュの合計サイズが小さくなる場合にメモリ量が減ることが分かった。だから、僕の修正が正しいこととOSは解放されたメモリを回収していることが分かった。

なお、必ずしもGCしなくても良い(GCはPythonに任せる)はずだが、今一つタイミングが遅い感じなので、(気分・好みの問題で)するようにした。

次に、推測ではあるが、画像が多いとメモリを食う理由も分かった。使って居るグラフィック処理系のGTKは、画像をGdkPixbuf(以下、Pixbuf)という形式で保持する。そして、(悪い予想が当たり、)Pixbufは非圧縮のフォーマットしかないため、JPEGやPNGの画像を表示させる場合でも展開するためにメモリ使用量が増大する(BMPみたいな感じ)。そのため、添付画像が多いノートを表示するとメモリ使用量が増大するのだ。

試しに、画像の多いノート※で検討してみた。

※このノートは定期的に同じグラフの画像をキャプチャして貼り付けているので、すべての画像のサイズがほとんど同じで、計算には都合が良い。

  • ノート内の埋め込み画像のサイズ: 約700x450 650x390px
    • → 上のサイズのPixbufの予想メモリ量: 923 990kB/画像 (700x450x3 650x390x4)
  • そのノートを読み込んだ(表示している)時のZimのメモリ使用量の増分: 約68MB
  • ノート内の埋め込み画像の数: 73
    • → 1画像当たりのメモリ量: 約950kB/画像 (68x1024/73)
      • ※このノートのテキストは約14 8.4kBと小さいので、ここでは無視した。

注: その後、実際のPixbufオブジェクトにはアルファチャネルがあって4チャネルであることと、実際の画像サイズは約650x390pix、テキストサイズが約8.4kBであることが分かったので修正した。 (9/16 11:00) ← どうしてサイズが違ったのか考えたら、元の画像は修正前のサイズだが、表示時に自動でリサイズしているためのようだ。 (9/16 13:29)

Pixbufの仕様から推算した1画像当たりのサイズとメモリ使用量の増分からの1画像当たりのサイズが合ったので、無駄にメモリ使用量が増大しているのでは なさそうなことが分かった。

(9/16 11:10) なお、実際のプログラムで画像のデータサイズを求めたところ、上と合っていた。: Pixbuf.get_byte_length()の値と、get_width()などの画像パラメタから上の方法で計算した画像サイズが一致した。

これを改善するには、TextBuffer(あるいは他のGTKの要素)で画像を圧縮したまま扱えれば(表示・コピー・ペースト・移動など)良いが、少し調べた限りでは できなさそうだ。ブラウザのように表示だけならともかく、編集までできるようにするのは難しい気がする。

ブラウザが どうやっているか分からないが、やっぱりPixbuf(あるいは同様の非圧縮フォーマット)の気がする。だから、あんなにメモリを食う(もちろん、これだけではない)のかも知れない。

(9/16 11:27) 他に、画像を読み込む時にアルファチャネルを削除すればデータサイズは3/4になるだろうが、根本的でない気がする。でも、ちょっとやってみたい。

B. 画像からのアルファチャネルの削除 (9/18 12:40)

苦心惨憺して できた。GTKには なぜかアルファチャネルを削除する処理(API)は なさそうなので、作った。処理自体は簡単なのだが(それでも分からないことが多かったので、楽ではなかった)、Pythonで書いたら遅過ぎた(元々の5倍くらい時間が掛かる)。

処理の概要: Pixbuf(アルファあり) → Bytes → アルファチャネル((インデックス%4)==3)を削除※ → Bytearray → Pixbuf(アルファなし)

※おもしろいことに、調べて見付かった凝ったデータ抽出方法([]内にループを書くようなやつ)より、普通に愚直にループ+配列のslice → extend()で書いたほうが速かった。[]内のループをコンパイルできるなら、速くなるのだろう。

まあ、元々心配していたが、いくらPythonが速くても こういう処理には無理がある。そこで、ネイティブで書かれたライブラリを使うことにし、元々Zimで使われていたので思い出した、PILというライブラリのconvert()という関数を使った。PILも、癖があったり資料が今一つ親切でないので苦労した。

処理の概要: Pixbuf(アルファあり) → Bytes → PILのImage("RGBA") → convert("RGB") → Bytearray → Pixbuf(アルファなし)

GTK→PIL(アルファ削除)→GTKとデータ変換が多くなったが、元々からの速度低下は ほとんどない。ページ読み込み(表示)時間は元々と変わらないのに速くなったように感じる(キャッシュされているページが一瞬で出る)のは、気のせいとかプラシボ効果だろうか。画像のサイズが小さいとかアルファがないために処理が軽くなった可能性もあるが、数値※は同じである。

※数値が変わらないのはキャッシュされていないページを最初に表示する時のことで、キャッシュされているページの表示は本当に速いのかも知れない。

メモリ量は、内部的(ページサイズ)には計算どおり3/4になったものの、OS(Linux)側では従来どおり多目に出る。まあ、仕方ないのだろう。: Pythonがプールして解放していないとか、解放してもLinuxが引き取らないなどかと想像している。

 

余談: Zimへの寄付について

今までずっと、「ちゃんと使う・使えるようになったら寄付しよう」※と思いつつも迷って居たが、止めた。

※そもそも、(良くあることだが、)PayPalでは日本から寄付できないし、PayPal以外の方法は示されていない。

本文に書いたように、オリジナルのままでは使いものにならないので寄付しないことにしたが、ベース(骨組み)としては随分役に立っており、良くあれだけの内容・量を作ったものだと感心しているので、きっぱり切り捨てられずに今一つモヤモヤしていた。

それで、僕の修正・改良のいくつか(例えば上述のHACKを不要にする方法)をフォーラムに投稿すれば充分に寄付の代わりになりそうだと思い付いたので、もう少し試用して改良が問題ないことが分かったら することにした。*

*が、今までの経験から、投稿しても大抵は無視とか放置になるのが分かっているので、最初は手を掛けないようにしたい。作者が興味を示したら、詳しく教えることにしよう。でも、詳しく書いたら放置や却下もあるので、そもそも手を掛けないようにしよう。

 

PS. Zimには全く関係ないが、フォーラムやユーザー対応で今までで一番良かった(親切・真摯だった)のはMusicBeeのSteven(うろ覚え)だったかも知れないと、今思い出した。だから僕は翻訳を したくなったのかも知れない。彼は今もMusicBeeの開発を続けているのだろうか?

 

(9/13 10:11 誤字を修正。: 「解放」と「開放」は難しい・・・, 15:36 「メモリ使用量についての検討」を追加, 19:15, 19:44, 20:39 少し修正・加筆, キーが取れない件に追加; 9/16 11:27 PixmapはPixbufの誤りだったので修正, ページサイズの推算でのパラメータを修正, 画像のデータサイズについてなどを追加; 9/18 12:40 画像からアルファチャネルを削除する処理について追加, 14:59 2重表示について追記)

  •  0
  •  1
Keys: , , , , , ,

先日、PCやサーバのバックアップに使って居るBackblaze B2から値上げ予定のメールが来た。ストレージ単価が20%も上がる(USD 0.005 → 0.006 /GB/月)ので、元々安いものの、こちらにはメリットがなく※、ただ値上げされた感じで、何とも気分が悪い。*

※例えば、「代わりに」毎月10-20GBくらい無料にしてくれたらうれしい。が、結構な損になるのだろうか?

*想像でしかないが、Backblazeは少し前に上場したために、コストが増大したとか売上や利益率を上げるように圧力を掛けられているのかも知れない。自分の経験からも、上場すると碌なことがない気がする。

そこで、(以前もやったが、)再び、無料の容量が比較的大きく、有料での単価の安いCloud (Object) Storage(バックアップに使って居るduplicacyで使えるもの)を探してみた。以下に それぞれの概要と印象を書く。また、実際に試したStorjについては その結果も書く。

  • × Storj: 比較的安いが、安定性、継続性、永続性の点で信用できない。
    • 無料: 25GB/月; 有料単価(storage): USD 0.004/GB/月
    • サイトに書かれている"Availability: 99.95%", "Endpoints: 20000+"は すごいように見えるが、良く考えると そうでもない。
      • 信頼性をうたうなら、Availabilityは99.99%以上要ると思うし、全世界で たった2万のノード(ストレージ提供者, 仮想通貨のマイナー相当?)しかないのは少ない。*
        • *いつまで続く(終わる)か不安がある。自分の周囲のストレージ(提供者)が居なくなったら、データが失われるのではないか。 → 継続性、永続性への疑念
    • なぜか、サイトに肝心な説明(「分散されたストレージ」とは具体的には何か)が明記されていない※のも腑に落ちない。(読み落とし?)
      • 結局、検索して調べると、Storjは仮想通貨のように、ストレージを提供してお金をもらう人たち(上述のマイナー相当?)に依存しているのではないか。だから、そういう人たちが「お金にならない」とか思って居なくなったら終わりだ。
        • 実際、以前は無料容量が100GB以上と多かったらしいのに今は随分減って居るのは、ストレージ(提供者)の確保が難しくなっているせいではないだろうか。
        • そういうことだと、環境に配慮していることもうたっているが、実際には環境に悪い気がする。: お金を稼ぐために、多少非効率でも容量や速度や帯域を大きくする人が多いのではないか?
      • ※僕は、最初はStorjのストレージ設備が全世界にあるように思い込んでしまったが、冷静に考えれば、それを安い料金で提供するのは無理だ。
    • duplicacyで使ってみて: 今一つ
      • デスクトップ(IPoE/DS-Lite接続)の場合、ネイティブプロトコルでは(DS-Liteの)IPv4のポートを使い尽くして*、バックアップがエラー(connect: no route to host)で止まった。※: エラー自体はduplicacyの実装の問題があるだろうが、このことで調べているうちに上の疑念が生じた。
        • *バックアップ中はPCから200以上のノード(周囲のストレージと思われる)に接続が起こる。PCやルータのリソースを使い尽くしてしまうことだけでも好ましいことではない。効率が悪いし、セキュリティ的にも どうかと思う。
          • あと、暗号化しているとは言え、自分のファイル(の断片)を周囲に撒き散らすのは、僕は受け入れられない。
          • その関係の保険なのか、規約に「個人情報、クレジットカード情報などを格納しない」のようなものがあったが、高い信頼性を うたう割には何に使うことを想定しているのか謎だ。
        • ※サーバはネイティブ?なIPv4/IPv6なので、ネイティブプロトコルでも問題なかった。
      • S3互換プロトコルならデスクトップでも大丈夫だったが、なぜか、バケットの情報(ファイル)がコンソールでは見えなかった。: S3の暗号化が違うためか?
        • 認証・暗号化に関しては、パスフレーズや認証キーなど種類が多くて(上記のようにプロトコル・アプリケーションごとに違う)、分かりにくく煩雑だった。
  • △- iDrive e2: 料金体系が悪い。恣意的?
    • 無料: 10GB/月; 有料単価(storage): USD 4/TB/月
    • 容量が1TB単位なので、今使って居るB2とGoogle Cloud Storage Archive (GCSA)を全部移すなら可だが、刻みが大き過ぎて高く付くし、単価はGCSAより高い。 → 以前は候補にしていたが、今一つな感じだ。
  • × IBM Cloud Object Storage: やっぱりIBM?: 無料は実用にならず、有料は高い。
    • 無料: 25GB/月; 有料単価(storage): USD 0.0237/GB/月
    • 無料容量は25GBだけど、無料でできる処理数が少なくて(例: Class A: 2000 → 一か月に2000ファイル(オブジェクト, ファイル)までしか作れない※)、実用にならない。
      • ※今のサーバのB2へのバックアップは約20GB, 約14000チャンク(オブジェクト)
    • 有料単価が高い。
  • その他: 信用できない・使えない印象。
    • × Scaleway: 不安が大きいので却下した。
      • 無料: 75GB
      • 評判が まちまちなので、先日騙されたOracleと同様に相手によって態度を変えているのだろうか。
      • 支払い方法(クレジットカード)を登録しないと使えないが、レビューを見ると、「使っていないのに課金されて返金されない」、「苦情を出しても課金され続けている」というのが結構多いので、登録を止めた。
      • また、上にも書いたが、Oracleのように、登録しても なぜか却下されて使えない(しかもデポジットが返金されない?)こともありそうで、イライラするのが嫌なこともあって止めた。
    • × Blomp (ファイルストレージ): 明らかに「うま過ぎる話」なので却下した。
      • 無料: 200GB
    • × Degoo (ファイルストレージ): うまい話ですらないので却下した。
      • 無料: 20GB
    • ×× TeraBox (ファイルストレージ): 無料では使い物にならないので却下した。
      • 無料: 1TBだが、20ファイルまでで話にならない。

 

という訳で、今回もB2から脱却することはできず、値上げされても使い続けるしかないという結論となった。B2が一枚上手だったようだ。: つまり、彼らは上のようなライバルの状況を把握しており、多少値上げしても優位に居続けられる・移る人は少ないことを理解して強気になっているのではないか。

あと、現状の僕のB2の料金は2か月でUSD 1程度なので、検討すること自体も割に合わないのだが、興味があるし世の中の流れを知るのも重要なので、比較・検討した。

 

PS. Storjについての疑問 (8/29 14:41)

Storjの うたう高信頼性(下に抜粋・引用)が疑わしいので、少し考えた。なお、Storjの仕組みについては ほとんど知らないので、あくまでも推測である。

Durability: 11 Nines, Availability: 99.95%, Encryption: AES-256 GCM

信頼性(耐久性・可用性)について

本文に書いたように、Storjはストレージの提供者(仮想通貨・暗号資産のマイナー相当?)のストレージに分散してデータを保存していると推測する。

すると、データを書き込む時にはStorjのサーバで分割して どの提供者(おそらく複数)に書き込むかを決め、書き込んだデータを取り出す時は、Storjのサーバから書き込んだ時の分割情報(またはそれへのポインタ: 分散して保存されているかも知れない)を取得するだろう。

とすると、信頼性を決めるのはStorjのサーバと(多くの)ストレージ提供者のストレージになる。: 前者の信頼性を高めることは可能だが、"Durability: 11 Nines"と言うほど確保できているのか疑問がある。Storjのサーバが全部消失したら全部のデータが失われるだろうが、どこまで強く・多重化・冗長化しているのだろうか。

次に、提供者のストレージの信頼性が確保・担保されているとは思えないので、ストレージ自体・単体の信頼性は かなり低いと想像できる。冗長化することで補っていると想像するが、それには限りがある。低い信頼性の掛け算で更に低くなった信頼性を冗長化で どこまで("11 Nines, 99.95%"?)高められるか疑問がある。

暗号化について

AES-256 GCMという暗号化をしているようだが、計算速度がどんどん増している現状で、絶対に解読できないとは思えない。悪意を持ったストレージ提供者が解読してユーザのデータ(の一部)を悪用できる可能性はないのか、疑問がある。 この場合、元のデータの生成元は分かっているし、いくらでも時間や手間が掛けられるだろうから、結構危うい気がする。その他に、Storjの仕組みに問題(バグ)があって、容易に解けるようになって居たとかいうこともあるかも知れない。

データを分割する時に、データの順序をブロック内でなくブロック間で入れ換えて居る(「スクランブル」している。: 例: ファイルの先頭ブロックの一部を後ろのほうのブロックの中間辺りに配置するようなことをファイル全体で行う)なら かなり強そうだが、結構手間が掛かりそうなので どうだろうか?

とは言え、実際には多くのユーザは更に自分で暗号化するだろうから、解読するのは容易ではないだろう。また、暗号資産の強度の議論とほとんど同じことだろうから、今の時点では問題ないのだろう。

 

(16:23 少し加筆・修正、構成を修正; 8/29 Storjのduplicacyでのエラーを追記; 8/29 14:41 PS. Storjについての疑問を追加)

  •  1
  •  1
Keys: , , , , , , , ,

先日検討した、最も「入る」(と考えられる)ゴミ箱の最初の版が出来た。いつものように段ボールを使い、長方形より多くのゴミが「入る」という点で8角形のものを作った。※ 僕にしては随分うまく行ったが、客観的には「夏休みの工作かな?」レベルであろう。

※前回の検討から、一番入るのは円(円柱)だが、作るのが困難なので8角形(8角柱)にした。8角形は、正方形(立方体)に近い長方形(直方体)の各辺の中央で折れば作れるので、比較的容易だと考えた。

見た目は どうであれ、自分なりに最適な形状を検討して実現できたのは、喜ばしいことだ。しかも、ちゃんと実用できる(耐久性は要観察だが)。

作りながら・出来てから、サッカーボール*や長岡鉄男マトリックススピーカー※を連想したが、前者は5+6角形, 後者は6角形(台形+長方形)のようだ。

*脇道に逸れるが、6角形だけでも敷き詰められるはずなのに、5角形も使うのはなぜだろうか?: デザイン的なもの? 縫製のしやすさ?

※再び脇道に逸れるが、8角形は平行な面が出来るので、スピーカーの箱には良くなさそうだ。

 

以下、細かい話などを書く。

苦労・工夫したこと

  • 本体: 上述のように、直方体(断面は ほぼ正方形)の段ボール箱の各短辺(上下底以外の面)を半分に折って ほぼ正8角形にした。
    • なので、(僕には)正6角形を作るのは無理である。細長い6角形ならできるが、面積が小さくなるので意味がない。
    • 6角形よりは容易だとは言え、8角形の角は直角でないので、正確に合わせるのは難しい。そこで、底板にも使った別の段ボールの大きさが丁度良かったので、その辺や段ボールの筋に8角形の直角になる4辺を合わせて整形した
    • また、引越しなどでの運搬を考慮して、今回は剥がせる両面テープを使って段ボールを貼り合わせた。
      • そうすれば、運搬時に剥がして分解できる※と考えた。が、実際には、底を外せば畳めるので、本体に関しては接着が良かった。 → もし剥がれたら接着する。
        • ※運送業者に注意するように言えば良いが、(無駄に)かさばるため、重い物を入れて両方を壊される可能性が高いので、それを防ぎたい。
      • 今気付いたが、そもそも、「剥がせる」両面テープと言っても紙に使った場合は綺麗には剥がれない(紙が剥がれる)だろうし、剥がせないタイプでも容易に剥がれるから意味がなかった。。。
      • 事前にマジックテープ(面ファスナー)も検討したが、意外に高いのと すぐには手に入らないのと、紙だと外す時にテープが剥がれる気がしたので止めた。
    • 作ってから開口部の周の強度が心配になったので、外に折り曲げた部分の切れ目に紙片をボンドで貼って繋げて補強した
  • 底: 別の段ボール箱に本体を載せ、本体の形に合わせて切って作り内側から嵌めて(見た目の良さで そうした)貼った。
    • このゴミ箱は中に物を入れたまま持ち上げて運ぶことは想定していないため、そのような簡単な固定にした。
  • ゴミ袋の固定: 普通のゴミ箱のように、上辺の縁に引っ掛けて折って固定したかった。が、段ボールが若干大きかったため、最初に作ったものは本質的に無理があった。
    • そこで本体を少し小さくした。ゴミ袋のサイズ(幅65cm)に合わせ、接合部分で約3cmずつ縮めた。
      • そのため、わずかに正8角形ではなくなり、底を外しても平らに畳めなくなった。が、面積は問題ないので良しとした。
  • : 見た目だけのものなので特に考えがなかったが、別の段ボール箱を開いたもののサイズが概ね合ったので、本体の形状に近く切って付けた。
  • その他
    • 辺や角が多い(8角形は四角形の2倍!)ので、全般的に手間が掛かった。
      • そのため、テープなども余計に使った気がする(そんなことはない?)。
      • また、角が直角でないため、ただでさえ工作が苦手なのと相まって、形が微妙に歪んだ
      • こういうことが、建築などで普通の四角形の柱が使われる理由の一つかも知れない。
    • 前回作ったプロト(四角形)と比べると、予想通り若干大きい(遠近法のため、写真ではプロトのほうが大きく見える)が、設置には問題ない。
      • ただ、個人の感想だが、見た目は こっちのほうが良い感じだ。シュッとしているとか、(形が)ちょっと おしゃれな感じがする。
      • まあ、形よりは、(ムカつく)パンダの絵などが見えなくて無地であることが大きいかもw
      • なお、蓋を付けた途端に、トイレの蓋みたいな感じで今一つになってしまう・・・

製作中などの写真

 

確認・検討など(サイズ, 容積, 断面積, 強度)

  • サイズ, 容積
    • 幅(内側): 約38cm (上述のように、作る時にサイズを小さくしたため、約39cmと約38cmが2つずつある。), 深さ: 約47cm → 容積: 約58l (ゴミ袋: 45l)
      • 容積がゴミ袋より随分大きいが、ゴミ袋の測定条件が不明(例: 縛る部分をどうしている?)なのと、このゴミ箱が若干大きい(角の部分が効いている?)からだろうか。
    • 辺の長さ: 約16cm (上と同じ理由で約17cmと約15cmが4本ずつあるので平均した。) → 断面積: 約0.12m2
  • 円などとの断面積の比較
    • 前回と同様にゴミ袋の幅をwとした時、8角形の辺の長さは2w/8 → w= 1とした時、辺の長さは2/8= 1/4 → 面積は0.31 (参照1, 参照2): 前回計算した円(0.32)に近い。
    • 参考: 6角形の場合、辺の長さは2w/6 → 2/6= 1/3 → 面積は0.29で、少し小さい。
  • 強度
    • 柱状のもので強い形状を調べたが、6角形あるいは円形の情報が多かった。
      • 構造材などでハニカムが強い話は見付かったが、実際の建築に使うには(現状では)余りメリットがないという情報もあった。 (→ 参照)
      • また、柱として使う場合は強いという情報があったが、今回と異なり、上から圧力を掛けた場合である。
    • 8角形は上からの圧力には強い情報はあったが(ただ、なぜか6角形より弱い実験結果もあった)、隙間なく配置できないため※、ハニカムのような構造は なかった。
      • ※前回は気付かなかったが、8角形は隙間なく配置できないので、6角形が最密だそうだ。
    • いずれにしても、主に柱の圧縮や曲げに関する強度の検討が中心で、今回のように中に物を入れた時の(柱の表面の膨らみ・縮み方向の圧力に対する)強度に関する情報は見付からなかった。
    • ただ、炭酸飲料の缶やPETボトルは、強度を稼ぐために素直な円柱にしているという情報があった。: 円は角(凸凹)がないために圧力が均等に掛かるから強いということだった。 (→ 参照) → 8角形は長方形よりは円に近いので、強そうな気はする。
  •  0
  •  2
Keys: ,

気付いたら前回から1か月も経っていた・・・ 億劫で本格的な着手は先週だったが、やっぱり手間が掛かって長引いた。約千個のJoplinのノート(画像などを含めたデータ量は約1GB)をZimに移した。

時間と手間は掛かったけど大したことはしておらず、移行スクリプトの作成・既存スクリプトへの機能追加・デバッグ・動作確認程度だ。以下に概要を書く。

ニッチな作業で普遍性がないうえに(手間の関係で)概要しか書けないので他の方の参考には ならないが、自分の整理として書く(詳細が知りたい方はコメントで質問されたい)。

Joplin→Zimへの移行処理

  1. Joplin→Zimの変換 (xfr-jop2zim.sh)
    1. 指定したJoplinのノート/ノートブック中のノートに対して次を行う。
    2. 対象のノートがZimに変換済みでない場合、そのノートをZimに変換する。
  2. Joplinのリソース(画像など)のZimへの取り込み (att-jop-rsrc.sh)
    1. 指定したZimのノート/ディレクトリ中のノートに対して次を行う。
    2. 対象のノートがJoplinのリソースを参照している場合、そのノート中のJoplinのリソースをZimのリソース(添付ファイル)にする。

1, 2どちらの処理用のスクリプトも これっきり使わない(はずの)ものだが、半ば無駄に高機能化した。例えば、Joplinのリソースを参照しているZimのノートの一覧を出す機能や、ノートブック内の全ノートだけでなく、子ノートブックに対しても再帰的に処理する機能などがある。

そうやって苦労したにも関わらず、もう、処理が2段階だったこと(スクリプトが2個あったこと)を忘れて居た・・・ (まあ、「これっきり使わないもの」ってのは そういうものだ。)

新たにプログラム(スクリプト)を作るのが面倒だし、誤りが多くなりそうなので、既存のもの(機能追加した)を流用・組み合わせた。

書いたあとで気付いたが、上の処理は「流用・組み合わせた」と書いたように、どちらも今まで または前回出来ていたもので、今回は それらを組み合わせただけだ。では何に苦労したかと思い起こすと、ノートの中には特殊なパターンがあって、想定する動作にならない場合があることと、多くのノートに対して 漏れなく2段階の処理をする(しかも結果の確認と処理の修正もする)という純粋な手間だった。

例えば、そもそもJoplinでもZimでも「エクスポート」するだけではリソースのファイルはコピーされず、そのままスマフォに送っても画像などが表示できないことがあるのでコピーし、ノート内のリソースの指定を そのコピーしたものに書き換える。その処理で、リソースの指定(≒ ディレクトリ)には いろいろな種類があり、それらを完全に把握して対応するのが難しいために上記の「特殊なパターン」が多発した。

それらの概要を以下に示す(以前にも書いた気がするが、変更もあるので再度書く)。

移行処理で使って居る処理の概要

  1. Joplin(MD) → Zimにエクスポート (jop2zim.sh): 元々使っていたものを若干修正した。
    • 基本的にはJoplinのMDをpandocでZimのフォーマットに変換すれば良いが、pandocだけでは うまく行かないので、以下のようにした。
      1. Joplinからノート(MD)を取得
        • Joplinでエクスポートされるものは不便なので、cliのcatでノートを取得している。
      2. 前処理
        • Zimに変換後では無理な処理をする。
        • Joplinのノートブック→Zimのディレクトリ変換, ノート・ノートブック中の特殊文字の対応, リソースディレクトリ, リソース(画像など)指定, 書式(改行他)の修正・調整, pandocの誤り対応
      3. MD→Zim変換 (pandocを使用)
      4. 後処理
        • 書式(改行, 見出しの下線他)の修正・調整, 僕が変更したZimタグへの対応
      5. 追加情報ファイルの作成
        • Joplinのノート・ノートブック情報, エクスポートした日時, 自動エクスポート(Zim→MD)の可否※などを格納する。
          • ※例えばMDはスマフォに送るので全部のノートを変換する必要はなく(全部送るとデータ量が増大する以外に、同期が頻繁になって電池消費が増える)、その選択に使って居る。
            • 今回は、全部を自動エクスポート不可にし、スマフォに送るものだけ設定変更することにした。
      6. Joplinのノートにエクスポート済みのタグを付ける。 (処理の繰り返しを防ぐため)
    • 備考
      • リソースはJoplinのディレクトリにあるものを参照する。
      • Joplinのcliが不便なので、sqlite3でJoplinのDBにアクセスしてノートやノートブックの情報を取得している。
  2. Joplinのリソース(画像など)をZimのリソースにする。 (zim2md.sh -AJI)
    • 下のZim→MDの処理と共通部分が多いので、機能追加した。処理内容は下を参照のこと。
  3. Zim → MDにエクスポート(主にスマフォでの閲覧用)時にZimのリソースをMDのリソースにする。 (zim2md.sh): 元々Zim→Joplinにエクスポートするスクリプト(zim2jop.sh)だったものを改造・機能追加した。
    • MD変換はZimのMDエクスポート機能だけでは うまく行かないので、以下のようにした。
      1. 追加情報ファイル(上述)のサポート
        • 例: 自動エクスポート不可の場合は処理しない。
      2. Zimのノートを一時ノートにコピーして前処理
        • MD変換後では無理な処理をする。
        • MD書式(水平線, 箇条書きのインデント, 引用, コードブロックなど)の修正・調整
        • リソース(画像など)の抽出・存在チェックも行う。
      3. Zimで一時ノートをMDにエクスポート
      4. MDを後処理
        • ノートの題の復元(追加), リソース指定(ディレクトリ)の修正
      5. MD(またはZim)にZim・Joplinのリソースをコピー
        • MDと同じディレクトリにリソースディレクトリを作ってコピーする。
        • Zimの埋め込みリソース(MDの"[alt](URL)"(画像でないもの, 先頭の!なし)に対応するもの)はPC内の任意のファイルが指定されるので、MDにコピーするサイズを制限している。
          • 全くコピーしないことも考えたが、多少でもスマフォで見られれば便利と考えた。
      6. MD(またはZimのノート)内のリソース指定(パス)を書き換え
        • Joplinのリソース
        • Zimのリソース

その他の作業

  • (延々と)準備・検討・確認, プログラム作成・修正, 動作確認, デバッグ・・・
  • ノートの記述、ファイル名、ディレクトリ構造などの修正・調整(修正できない/面倒な/1回しか起こらず、以降も使わない場合)
    • 手抜きだが、もう使わないプログラムを手間を掛けて直すのは馬鹿らしいので。
  • Zim内のJoplinのリソース(sym-linkで参照)の無効化 (何らかの手違いで参照されたらエラーで分かるように)
  • MD内のJoplinのリソースの削除(不要になったので)

その他

  • 元々Evernoteだったノートは、変換を繰り返した(Evernote→Joplin→Zim)ためにフォーマット(特に改行、水平線、箇条書き)が ひどいことになっているが、文章は損なわれていないはずなので、良しとした。
    • 途中でDropbox Paperを使ったり、LinuxではNixnoteを使っていたこともあって、かなり ひどいものがある。下の画像抜けは その関係があるかも知れない。
  • Evernoteから移行したものでは画像が なくなっていることが結構あり、自分で処理したとは言え、汎用性のないフォーマット・サービスは良くないと思った。
  • スクリプト(特にzim2md.sh)は場当たり的な修正が多くなってしまい、肥大化・複雑化して自分でも全容・詳細が把握できなくなってしまったが、作り直すのは大変なので仕方ない? (どこかの銀行みたいだ・・・)
    • 「*すれば(手軽に)できそうだ」みたいな始め方が悪かったのは認めるが、そうでもないと始まらなかった。
  • 当然ながら、もうJoplinのDB(約170MB)を変更しなくなったので、自動バックアップでのデータ量が減った。変更があると100MB以上(PC全体での量、以下同)だったのが、数十MB(50MB以下の場合も多い)になった。
  • 今後、Zimから他に移る可能性があるかも知れないが、その時は汎用的なMDに変換できるので楽そうだ(実際には やっぱり大変だろうw)。
  • 上で「MDは汎用的」と書いたが、実際には いろいろな種類(流派)があるうえに機能が今ひとつだ。例えば、上・下付きの書式が統一されていない(というか、ない!)。外にも少し(ものすごくではない: 逆に、ものすごい機能はある)凝ったことをしようとすると、非互換かHTMLや外部機能に頼る羽目になって、「何考えてるんだ?」と思う。それが僕がZimを使って居る理由の一つだ。
    • まあ、ZimはZimで欠点(問題点/不具合)は いろいろある・・・ が、機能面では僕には最適・必要充分に近い。

 

PS. 以前からのTODOが一つ消化できた。が、次にはゴミ箱タイヤ交換PC・サーバのOSなどの更新が控えている。そう言えばスマフォの交換(買い替え)もあったな。依然として どれも面倒だw

PS2. 本文に書いた「特殊なパターン」に苦労したことで思ったが、僕でさえ そういうことを想定して少しずつ試しに処理して確認・修正しながら進めたのに、ある国の何とかカードの保険証は一気に国全体で始めてしまい、案の定、問題が多発している。「(いいシステムなので)問題は ないと思う(分からん)が、何かあったら現場で頑張れ」のスタンスかと思われるが、そういうのはプロとして恥ずかしい限りだ。まあ、大層な名前や肩書だけど、頭でっかち・口ばっかりでプロじゃないんだろう。

詭弁的な言い訳に、「発生率は極小なので、大きな問題ではない」とかいう、いかにも納得しそうなものがあるが、そういうレアな問題にもシステムの正当性・安全性に疑問を生じさせたり危険性を示すものがある可能性があるので、軽視してはいけない。

そういうことを考慮しない発言をすること、更に、その状況でも なぜか(どういう論理か不明だが)「安心」させて「数」を増やそうと企むことが、指揮者・発注者として失格というか、「無知無能は すっこんでろ!」だ。

そういう連中を弁護する意見に「トラブル0を求めるのは日本人の悪い癖」のようなものがあるが、それとは違う。トラブルを0にすること(無理だ)が目的とか重要なのでなく、起こったトラブルの原因を調べて、例えばシステムに予期せぬ問題がないか調べる・確かめることが重要なのだ。その結果、起こったトラブルが予期されたものであれば仕方ないし、安心できる。

言い換えれば、「問題は必ず起こるが、「だから問題ない」と言ったり、なかったことにするのは間違っている。」だ。

(8/22 4:59 加筆, 6:53 PS2を追加)

  •  1
  •  1
Keys: , , , , ,

昨日に引き続き頭の体操。基本的に数学などは苦手だが、馬鹿馬鹿しいことを真面目に考えるのは好きだw

 

結構前から、ゴミ袋が一杯になって収集に出そうとしてゴミ箱から出すと、まだ余裕があることに気付いていた。仕方ないので、一旦その袋を出して次の回まで別の場所に置いておき、実際に出す時に それまでの分を追加していた。が、どうも面倒だし汚いし、置き場所が もったいない。それで、どうしてそうなるかを考えたら、どうも、ゴミ箱の形が悪い気がして来た。

元々、今のゴミ箱は底に行くに従って狭まるのと、底部に蓋開閉用の出っ張りがあるので、そのせいかと思ったが、それ以上に、そもそもの形(主に断面)が関係しているのではないかと考えた。つまり、同じ袋でも断面の形によって入る量(体積)が違うのではないかと。

それで、もしそうなら、どういうゴミ箱の形ならゴミ袋に最大に詰められる(「入る」)のか考えてみた。この時、正確に考えるのは難しいので、以下の前提とした。

  • ゴミ袋の周(4辺の長さの和)はゴミ箱の形状に関わらず一定。
  • ゴミ袋はゴミ箱に密着する(ゴミ箱の形と同じになる)。
  • ゴミ袋をゴミ箱に入れた時の深さはゴミ箱の形状に関わらず一定(ゴミ箱が充分深い場合)。
    • 少し怪しいが、とりあえず成り立つとする。

すると、体積= 断面積 x 深さなので、断面積が最大になる形状のゴミ箱が一番「入る」と考えられるので、その形状を考える。

ゴミ袋のサイズを幅w x 深さhとして、一般的な形のゴミ箱の断面積を比較する。

※参考: 実際のゴミ袋(45l)のサイズ: 65 x 80cm → 可能な円周: 約130cm → 半径: 約20.7cm (直径: 約41cm), 正方形の場合の1辺: 約32.5cm

    • 断面積(r: 半径): S1= π r2
    • ゴミ袋のサイズと断面積の関係: S1= w2
      • 2πr= 2w → r= w/π → S1= π (w/π)2= w2
    • 参考:
      • 45lゴミ袋での断面積: 約1320cm2
      • 製品のサイズの例: 直径 43cm x 深さ: 47cm → 面積: 約1450cm2, 体積: 約68l (外寸なので大きい?)
  • 正方形
    • 断面積(L: 1辺の長さ): S2= L2
    • ゴミ袋のサイズと断面積の関係: S2= w2/4
      • 4L= 2w → L= w/2 → S2= (w/2)2= w2/4
    • 参考:
      • 45lゴミ袋での断面積: 約1056cm2
      • 製品のサイズの例(手頃なものは ほとんどない): 32cm角 x 深さ: 63cm → 面積: 約1024cm2, 体積: 約64l
        • 33cm角とすると、約1090cm2
        • 35cm角とすると、約1200cm2 (ゴミ袋のサイズから不可能)
  • 長方形
    • 断面積(L1, L2: それぞれ短・長辺の長さ): S3= L1 L2
    • アスペクト比(長辺/短辺)をRとすると、L2= R L1 → S3= R L12
    • ゴミ袋のサイズと断面積の関係: S3= R (w/(1+R))2
      • 2(L1(1+R))= 2w → L1= w/(1+R) → S3= L1 L2= (w/(1+R))(R w/(1+R)) = R (w/(1+R))2
      • 例: R= 1.5の場合、S3= 1.5 (w/(1+1.5))2= w2/(6.25/1.5)= w2/4.2
    • 参考:
      • 45lゴミ袋での断面積(R= 1.5の時): 約1014cm2
      • 現状のゴミ箱: R=約1.5 → S3= 1.5 L12
        • サイズ(内寸): 約25 x 38cm x 深さ: 53cm → 面積: 約950cm2, 体積: 約50l

※楕円も気になるが、そういう製品は ないので省略する。

それぞれの形状の断面積を比較すると、以下になる。

以下で、w: ゴミ箱の幅, R: 長方形のアスペクト比(長辺/短辺)である。参考のため、w= 1(単位長さ), 長方形のRをいくつかの値とした時の断面積も書く。

  • 円: w2
    • w= 1の時の断面積: 0.32
  • 正方形: w2/4: π≒ 3.14なので、円より小さい。
    • w= 1の時の断面積: 0.25
  • 長方形: R (w/(1+R))2: 複雑だが、R>1なので、正方形(左でR= 1とした場合)より小さそう。
    • w= 1, R= 1.25の時の断面積: 0.25
    • w= 1, R= 1.5の時の断面積: 0.24
    • w= 1, R= 2の時の断面積: 0.22

結局、円が最も断面積が大きいので、

同じ深さのゴミ箱であれば、断面が円のものが最も「入る」。

という結論になる。

最初に思ったことだが、直感的に、ゴミ袋の自然な形(収集に出す時の形)が球に近いので、それに近い円筒が良いのではないか。

更に、実際には、角型の箱だと四隅に物(ゴミ)が詰まりにくい感じなので、その点でも円筒が最適と推測する。

 

なお、製品を探すと、どういう訳か(部屋に置いた時の空間効率や見た目?)、実際には、長方形のゴミ箱が最も多く、次は円(主に屋外用)、正方形は ほとんどなかった。

なお、ゴミ袋ホルダー(箱なし)が最も効率が良さそうだが、見た目や強度の点で問題があるので採用できない。

ゴミ袋のためにゴミ箱を買い換えるのは馬鹿らしい気もする(ゴミ箱は意外に安くない)が、もし買うなら、円か正方形に近い長方形のものを探すことにした。

ただ、上の参考断面積を見ると、正方形になった時点で随分円より小さくなる(約3割減)し、意外に、アスペクト比1.5の長方形でも正方形と同様なので、円一択だろうか。

(16:41) 丁度良いサイズの段ボール(サイズ: 約35x35x53cm)があったので、試しに作ってみた。円に近付けるため、8角形に したかった※が、技術が ないので欲張らずに(ほぼ)正方形にした。安直に段ボールを縦にして天面にゴミ袋くらいの穴を開けた(ちょっと大きかった)だけだ。

※8角形などの場合、特に底面や蓋が難しい。

操作性や耐久性には難があるが、これで どのくらい入るかを試してみたい。良ければ ちゃんと作るか買おう。

なお、汚いので写真は載せないが、従来の長方形のゴミ箱で満杯になっ(て押し込めなかっ)たゴミを押し込めた※から、より入りそうな気がする。

正方形や円(→ 上に書いた球)に近いほうがゴミを圧縮しやすいのだろうか? ゴミが分散しやすいのか。袋を移したためにゴミが分散したとかの偶然かも知れないが。

は全くの僥倖で出来たもので、見た目は悪くないが、臭いは防げない。が、元のゴミ箱の蓋も通気性があるらしく、臭いは防げなかったので、大きな問題はなさそうだ。

(8/16 21:15) プロトタイプのゴミ箱は随分詰め込める感じだ。誇張なしで今までで一番だ。まだ隙間はありそうだけど、もう詰められないと思って袋を出そうとしたら なかなか出せず、口が縛れなくてガムテープで貼った。だから、円筒形状なら きっと最高に入るだろうけど、正方形でも充分な感じだ。

そう言えば、高校の化学で「六方細密」というの(分子配置?)を教わったのを思い出したが、8角形よりも6角形のほうが空間効率が高いのだろうか? ちょっと興味が湧いたが、ゴミ箱には正方形でも充分なことは分かったw

全くの余談だけど、その化学の先生が「落ち着いた おばさん(でも、どこか可愛気がある)」て感じで なかなか良かった。

ちょっと検索したら、どういう訳か、2次元で6角形(六方細密充填構造)まではあるが、8角形の構造はなさそうだ。自然には できない形なのだろうか。

(8/25 22:07) 8角形は隙間なく配置できないので(これを書いた時は気付かなかった)、6角形が最密とのことだ。

まあ、「細密充填構造」とは言っても、これはその元素の原子が細密なのであって、中に物(ゴミ)が最も充填できるとか、その形状の物が周囲との無駄が少なく配置できる訳ではなさそうなので、余り関係ないかも知れない。実際、面心立方格子構造(正方形)も六方細密と同じ充填率(74%)だ。

 

PS. きっと、形による面積の違いは既知の話なのだろうが、良く考えると不思議だ。周が同じで形が違うから面積が違うのだろうか? それにしても、減った分は どこに行ったのだろうか??

↑ 答えではないが、(箱または袋の)形を伸ばして直線にすると(= 袋を畳んだ状態)面積が0になるのと関係がありそうだ。少なくとも、同じ周の長さでも、形によって面積が変わることは確かだ。

変わる面積は一体どこに行く・どこから来るのかは分からないが、おもしろいことだ。

PS2. 現実には ありえないけど算数の問題に ありそうな例として、すごく長いロープで囲めるだけの土地をもらえる場合、利口は円にし、細長い形にするのは馬鹿ということになる。でも実際には、円だと きっちり分けられないから嫌がられそうだ。

なお、一休さんのような人は すごく小さい円を置いて、「どうした?」と聞かれると、「外側を全部下さい!」とか言いそうだ(が、相手が悪いと ひどいことになりそうだ)www

そこで6角形??w

 

(18:38 少し加筆・調整など; 8/15 19:54 副題を追加; 8/16 21:15 プロトタイプ ゴミ箱の感想を追記; 8/25 22:07 六方細密に補足)

  •  0
  •  1
Keys: ,