ぐるっとぐりっど

日曜プログラマがいろいろ試してみたことを、後の自分のためにまとめておく場所

書籍の情報を検索して挿入するためのHelmインタフェースを作ってみた

前回grugrut.hatenablog.jpの続き

やりたかったこと

org-modeで本の記録を取るのに、いちいち著者情報を手入力するのがきつすぎるので、検索していいかんじにバッファに挿入させたかった。
で、それを実現するのにHelmインタフェースで作るのが、それっぽいかんじで良さそうだったので、そうした。

HelmインタフェースもAnythingインタフェースも作ったことなかったので、やってみたかったというのもある

できたもの

github.com

使いかた

requireして、M-x helm-booksするといつものHelmインタフェースが表示される。
そして入力すると入力した文言に対してgoogle books apiに対してクエリが発行されて結果がリストとして表示される。

f:id:grugrut:20170320153659p:plain

Actionとしては、挿入する文章を変数"helm-books-custom-format"で設定することができる。

org-modeとの統合

org-captureでは、テンプレートに

(setq org-capture-templates
        '(("b" "book memo" entry
           (file (concat org-directory "book.org"))
           "* %(helm-books)"
          ))))

のように、%(sexp)とすることで、S式を埋め込むことができる。
これを利用することで、このテンプレートを呼び出すと、自動でhelm-booksが呼ばれ、本を検索し、必要な情報をプロパティとして設定したメモを簡単に取ることができる。

これはすごい

今後

  • ActionがInsertしかないので、他のActionを増やす
  • 情報源がgoogle books apiだけだが、検索結果が気持ち心許無いので、他のAPIからも取得できるようにする

Emacs Lispテクニックバイブル

Emacs Lispテクニックバイブル

本の情報を取得するためのHelm拡張を作ってみた(途中)

続きを書いた
grugrut.hatenablog.jp


init.el読書会で、org-modeのメモを読書記録にするための、org-captureのテンプレートがあって、やりたかったのだけど、いちいち本の情報をプロパティに手打ちするのは面倒だと思った。

* ゼロから作るDeep Learning 
:PROPERTIES:
:Author: 斎藤 康毅
:Year: 2016
:Publisher: オライリー
:END:

なんか皆やってそうなので、こういう情報を簡単に挿入できるような良いパッケージが無いか探してみたのだけど、みつけられなかったので、Helm拡張として作ってみることにした。

作るにあたっては、
helm拡張を書く - Qiita
Developing · emacs-helm/helm Wiki · GitHub
を超参考にした。

現状

f:id:grugrut:20170315222257p:plain

google books apiを使って、本の情報を引っぱってきている。
現状では、検索文字列が決めうち(emacs)、Actionは未定義で、候補が表示されるところまでできている。

入力するたびにAPIを呼ぶことになりそうなので、性能問題や、API呼びすぎてブロックされないかがちょっと心配

Helm拡張書いてみての感想

まだsourceの定義の一部しか終わってないけど、はじめとっつきにくい印象(公式documentもそこまで充実してないし)だったけど、ちょっとずつ書いてみたら、意外とあっさり書けた。
actionの定義はもっと簡単そうな気がするので、この調子でちゃんと完成させたい。

Emacs Lispテクニックバイブル

Emacs Lispテクニックバイブル

気象庁の時系列データをRで遊んでみた

はじめに

最近時系列データの解析に興味があって、いろいろと調べてたけれども、実データでないといまいちピンとこないので、いろいろとRの使いかたを調べつつ遊んでみた。emacsでもessをセッティングしているからいくらでもできるのだけど、せっかくなのでRStudioを使ってみた。

現場ですぐ使える時系列データ分析 ~データサイエンティストのための基礎知識~

現場ですぐ使える時系列データ分析 ~データサイエンティストのための基礎知識~

元データ

気象庁が過去の天気データを公開してくれているので、こちらを利用した。
いろいろとデータの種別やら期間やらあるけど、今回は1877年から2006年までの東京の月平均気温を使っている。

気象庁|過去の気象データ・ダウンロード

とりあえず読み込む

> tokyo <- read.csv("data.csv")
> View(tokyo)
> tokyo
        年月 平均気温
1     1877/1      3.2
2     1877/2      3.6
3     1877/3      6.2
4     1877/4     13.6
5     1877/5     16.5
6     1877/6     22.0
7     1877/7     26.5
8     1877/8     25.9
9     1877/9     21.3
10   1877/10     15.9
11   1877/11      9.6
12   1877/12      5.8
13    1878/1      2.3
(後略)

本来は、csvにコメント部分や他の列もあるけど、そこは先に加工したものを取り込んだ。read.csvでそのへんはカバーできるので実は不要であるが。

とりあえずデータテーブルだと扱いづらいので、平均気温を年ごとに扱えるように分割しておく。
はじめ2次元配列に分割しようとして、なんかうまくいかないと悩んでたけど、3次元配列にしてみたらうまくいったのでよかった。

> splited_tokyo = array(tokyo$平均気温, dim=c(1,12,140))
> splited_tokyo[1, 1:12, 1:3]
      [,1] [,2] [,3]
 [1,]  3.2  2.3  3.2
 [2,]  3.6  2.5  5.4
 [3,]  6.2  7.2  8.0
 [4,] 13.6 11.5 12.6
 [5,] 16.5 18.3 18.0
 [6,] 22.0 20.0 21.4
 [7,] 26.5 26.0 26.1
 [8,] 25.9 24.6 26.6
 [9,] 21.3 22.8 21.3
[10,] 15.9 15.8 15.0
[11,]  9.6  9.7  9.7
[12,]  5.8  5.1  8.0

とりあえずグラフ化してみる

複数の時系列データをグラフ化するなら、ts.plotを使うのが簡単

> ts.plot(splited_tokyo[,,], type ="l")

f:id:grugrut:20170226202340p:plain

140年分のデータをまとめてみると、やっぱり毎年同じように気温は変化する(1月2月が一番寒くて、8月が一番暑い)ということがわかるね。

20年ごとの相関も見てみた。

> pairs(splited_tokyo[1,1:12,c(1,21,41,61,81,101,121,140)])

f:id:grugrut:20170226203601p:plain

細かいところをみると違うところもあるけど、ほぼ一直線上にプロットされており、かなり相関係数は1に近いといえそう(計算して出せよ、というのは正しいがやってない)

過去と比べてみる

温暖化温暖化っていうけど、本当に昔に比べて気温はあがってるのだろうか。

とりあえず時系列データということで、tsで時系列データに変換する

> ts_tokyo <- ts(data=tokyo$平均気温, start=c(1877, 1), frequency=12)
> plot(ts_tokyo)

f:id:grugrut:20170226205023p:plain

なんとなく上昇傾向にある気はするけど、よくわからない

> plot(stl(ts_tokyo, s.window="periodic"))

f:id:grugrut:20170226205313p:plain

トレンドは確かに上昇傾向にあるけど、残差も多いのではなかろうか、これ。ただ、残差はプラスマイナス両方に散らばってるので、全体としては上昇傾向にある気がする。

ARIMAモデルによる推定もしてみた。

> library("forecast")
> arima_tokyo <- auto.arima(ts_tokyo, trace=T, stepwise=F, seasonal=T)
> plot(forecast(arima_tokyo, c(95), h=480))

[f:id:grugrut:20170226210851p:plain]

これは、2050年には1年中16度ぐらいの過ごしやすかちょっと肌寒いぐらいの気温になる、ということであろうか。

* 別アプローチ

1877年から1976年までの平均、標準偏差に対し、1977年から2016年までの値がどれぐらいの範囲にいるかを調べてみた。

>|r|
> m <- apply(splited_tokyo[1,1:12,1:100], 1, function(v){return (mean(v))})[1:12]
> m
 [1]  3.482  4.183  7.277 12.951 17.226 20.815 24.694 26.057
 [9] 22.367 16.403 10.982  5.873
> s <- apply(splited_tokyo[1,1:12,1:100], 1, function(v){return (sd(v))})[1:12]
> s

> ts.plot(splited_tokyo[,,101:140], type ="l")
> lines(m-3*s, type = "l", col="red", lwd="3")
> lines(m-2*s, type = "l", col="yellow", lwd="3")
> lines(m-s, type = "l", col="green", lwd="3")
> lines(m, type = "l", col="blue", lwd="3")
> lines(m+s, type = "l", col="green", lwd="3")
> lines(m+2*s, type = "l", col="yellow", lwd="3")
> lines(m+3*s, type = "l", col="red", lwd="3")

f:id:grugrut:20170226220823p:plain

赤が3σ、黄色が2σ、青が1σなので、気温が全体的に高くなってるように見える。

計算ミスでないことを角煮するために、1877年から1916年までの40年間で同様に確認してみると、

f:id:grugrut:20170226221051p:plain

と、だいたいが1σ、外れ値っぽいところでもほぼ2σの範囲にはおさまってるので、データとしては問題なさそう。とはいえ最近寒くて閉口してるけどね。

まとめ

Rたーのしー!!

以下の本も買ったけど、見た目によらずかなり教科書教科書してて読みきれてない。

Rによる時系列分析入門

Rによる時系列分析入門

zenburnテーマのregionのbackgroundが見辛かったのでテーマを少しいじった

はじめに

しばらくmisteriosoをテーマとして使ってたけど、最近はzenburnを使ってる。
理由は簡単で、Emacs Theme Gallaryで最も人気が高かったから。
https://pawelbx.github.io/emacs-theme-gallery/

落ち着いた色合いが気に入っているといえばそうなんだけど、気になるところもいくつかあり、そのひとつが色が弱々しくて視認性が悪いところ。
特に範囲選択したところ、リージョンの背景が色の違いがなさすぎてつらい。

f:id:grugrut:20170213223901p:plain

これならまだわかる

f:id:grugrut:20170213223946p:plain

単語レベルでmultiple-cursors使おうとすると、もうダメ

色のカスタマイズ

zenburnテーマは、zenburn-with-color-variablesマクロで各faceの設定をしてるので、init.elにこんな感じの設定をいれてみた。

(zenburn-with-color-variables
    (custom-theme-set-faces
     'zenburn
     `(region ((t (:background ,zenburn-bg-2))))))

zenburn-bg-2は、いってしまえば、#000000と、完全なる黒なのだけど、これぐらい極端にやったほうがよい感じ。

f:id:grugrut:20170213224247p:plain
くっきり表示される。

f:id:grugrut:20170213224252p:plain
単語レベルでもこの通り。

おまけ

github.com

zenburnのissueには、「他のテーマは、regionが通常の箇所より明るい色が普通だから、もっと明るい色使おうぜ!」って提案されてるものの「そんなんしたら見辛くなるじゃん」と一蹴されてた(issueだけに)。

その通りだと思うけど、デフォルトも十分見辛いと思う。スタイリッシュさが失なわれるのは確かなので、おとなしく他のテーマに移ることも検討しよ。

Google Code Jamに向けて、goで雛形を書いてみた

遅ればせながら、最近Go言語に興味が出てきたので、普段はGCJ(Google Code Jam)をはじめ、競技プログラミングJavaで書いているけど、その雛形をgoでリライトしてみた。

github.com

だいたい競技プログラミングのinputはスペース区切りのテキストで、outputは一行で、というのが基本なので、それに対応しているはず。

outメソッドがあらかじめfmt.Sprintf()で整形したstringを渡すことを前提としていて、若干使いづらいのが難点で、

out(fmt.Sprintf("Case #%v: my answer\n", test))

と渡さなければならない。

func out(format string, s ...interface{}) {
	fmt.Printf(format, s)
}

で、仲介できると思ったのだけど、期待通りは動かなかった(複数渡した引数が、配列?として渡ってしまう)。

さすがに、渡し方はあるはずなので、さらに調査が必要そう。

fmtパッケージのソースを見るのが一番てっとり早いのかな。

みんなのGo言語[現場で使える実践テクニック]

みんなのGo言語[現場で使える実践テクニック]

org-modeで計時(Clocking)する際に特定のTODOキーワードの場合だけ状態変更する

この記事は、.emacs Advent Calendar 2016の18日目の記事です。

org-modeの小ネタです。

はじめに

org-modeではTODO管理の中で、そのタスクにかかった時間を計測することができるようになっています。

C-c C-x C-i→時間計測を開始する(clock-in)

C-c C-x C-o→時間計測を終了する(clock-out)

で、便利なことに、clock-inした場合に、自動でTODOキーワードを変更することができます。

;; 時間計測を開始したら自動でSTARTED状態にする
(setq org-clock-in-switch-to-state "STARTED")

これをやっておくと、未着手のTODOを着手(時間計測開始)すると、STARETEDになり、着手済か未着手かがわかりやすくなるというわけです。

f:id:grugrut:20161217161555p:plain

Aプロジェクトを開始した状態。AプロジェクトはSTARTEDと表示され、BプロジェクトはTODOのままになっている。また、モードラインには計時しているタスクが表示されるのも便利。


org-captureを活用すると、タスクに着手している際に割り込み(電話等)が入って中断された場合でも、割り込まれたものも含め簡単に計時することができます。詳しくはこちらの過去記事をご覧ください。

grugrut.hatenablog.jp

このやりかたで困ったこと

そんなこんなでやってたのですが、困ったことがおきました。

それがこれです。

f:id:grugrut:20161217162528p:plain

本当のTODOも、一時的に実施していたTODOで無い作業も、ミーティングのような計時だけしておきたいものもすべて、clock-inすると皆STARTED状態になってしまって、何が本当のTODOなのかわからなくなってしまうのです(今回は例として適当に作りましたが、実際はもっと雑多なものが30個近くたまってしまいました)。

本当は、GTDでは日次レビュー、週次レビューは基本なので、その中で不要なものを完了状態にしていくのが基本なのですが、そうはいっても、これだけたまると片付けるのも面倒だし、そもそも計時だけしたいものをいちいち完了に変更するのも面倒だし、ということで、モチベーションがかなり下がってしまいました。

計時だけして、TODOでないものは、TODOキーワードいらないようにできないだろうか、と虫の良いことを考えていました。

そんな都合のよいやりかた

実はorg-clock-in-switch-to-stateには関数を指定することができます(できること自体は知ってたけど、わざわざそれをする意味がわかってなかった)。

;; 時間計測を開始したらSTARTED状態に
(setq org-clock-in-switch-to-state 'my-org-clock-in-switch-to-state)

;;; TODOの場合だけSTARTEDに変更する
(defun my-org-clock-in-switch-to-state (state)
  (when (or (string-equal state "TODO")
            (string-equal state "STARTED"))
    "STARTED"))

my-org-clock-in-switch-to-stateには前の状態のTODOキーワードが入ってくるので、TODOか既にSTARTEDの場合のみ"STARTED"を返すようになっています(よくよく見直すとSTARTEDを条件に入れる必要ないし、ヒットしない場合はstateをそのまま返したほうがよいのかな?)

そうするとこんな感じで、TODOに設定していない場合は、STRATEDが設定されないので、org-agendaを汚さないで良いかんじ。
f:id:grugrut:20161217163729p:plain

まとめ

他の人の.emacsを読んでて知ったのだけど、なぜそんな設定をしているのか想像しながら読むと勉強になるね

明日はtakaxpさんの「高速起動用ミニマム*scratch*バッファ」の予定です。楽しみですね。

Emacs25に導入されたXWidgetに関して理解を深める

この記事は、Emacs Advent Calendar 2016の3日目の記事です。

はじめに

emacs25.1が2016年9月17日にリリースされました。
なかでも注目を(個人的に)浴びていたのが、もともとブランチして開発されていたものがマージされたXWidgetsです。

XWidgetsは、リリースノートを見てみると、

Xwidgets: a new feature for embedding native widgets inside Emacs buffers.

https://www.gnu.org/software/emacs/news/NEWS.25.1

と、ネイティブなウィジェットemacsのバッファに埋め込めるらしいです。
実際なにができるか用途がぱっとは思い浮ばないものの、可能性としてはおもしろいと思います。

EmacsWikiの記事を見てみると、emacsの中にemacsを埋め込むという、よくわからない状況になっています。

EmacsWiki: Emacs X Widgets


ただ、実際のところ、巷のブログ等見てみても、xwidget-webkit-browse-urlコマンドを使ってみた、程度の記事しかみつからず、ウィジェットの挿入方法がよくわかなかったので、ウィジェットの挿入方法を調べてみました。

(結論から書いておくと、emacs 25.1では、任意のウィジェットを挿入することはできません。M-x xwidget-webkit-browse-urlでネイティブブラウザをバッファに表示するぐらいしかできません)

ビルド

Xwidgetsはどのemacsでも利用できるわけではなく、ビルド時に、--with-xwidgetをつけた場合のみ利用することができます。
Xwidgetsが使えるかどうかは、M-x xwidget-webkit-browse-urlを実行してみるのがてっとりばやいと思います。有効でない場合は、

Your Emacs was not compiled with xwidgets support

と優しく教えてくれます。なお、xwidget-webkit-browse-urlの使い方は巷にあふれているので、そちらに譲ることにして、ここでは割愛します。

--with-xwidgetオプションを利用できるのは、今のところLinux(Unix)、Mac OSWindowsCygwin上のみのようです。Bash On Ubuntu On Windows上やmsys上でできないか調べたり、いろいろ試したりしてみたのですが、X Serverが無いので駄目のようです。残念。

サンプルコード

任意のWidgetとして、ボタンを挿入する超簡単なサンプルコードです。

(require 'xwidget)
(xwidget-insert (point-min) 'Button "Click me" 100 100)

これを評価すれば、

f:id:grugrut:20161129143317p:plain

な感じでボタンが表示されます。ボタンだったら、M-x customizeでも表示されるじゃんと思ってそちらのボタンも見てみたのですが、ちょっと見た目が違いますね。

f:id:grugrut:20161129143534p:plain

もちろんボタンだけでなく、スライダーや他のGtkWidgetを挿入することもできます。

(xwidget-insert (point) 'slider "slide me" 300 50)

(xwgir-require-namespace "Gtk" "3.0")
(put 'ColorButton1 :xwgir-class '("Gtk" "ColorSelection"))
(xwidget-insert (point) 'ColorButton1 "xwgir-color-button " 500 300)

f:id:grugrut:20161203122417p:plain

(put 'ColorButton1 :xwgir-class '("Gtk" "ColorSelection"))

で、デフォルトでは設定されていないwidgetを設定できるようなのですが、
https://developer.gnome.org/gtk3/stable/GtkWidget.html
配下にあるクラスをセットしても、表示されるものと表示されないものがあるので、なにかしら表示できるwidgetに条件があるようなのですが、そこは残念ながらわかっていません。

苦しんだところ

実はこのサンプルコード、emacs 25.1では動作しません。
評価するとセグフォでコアを吐いてemacsが死んでしまいます。ビルドミスかと思って調べたら、emacs 25.1の方には制限をかけてあってxwidget-webkit-browse-url以外の用途では使えないようになっているようです。

Xwidgetブランチのコードにあるsrc/xwidget.c
http://bzr.savannah.gnu.org/lh/emacs/xwidget/files

DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 8, 0,
         doc: /* Make an xwidget from BEG to END of TYPE. 

If BUFFER is nil it uses the current buffer. If BUFFER is a string and
no such buffer exists, it is created.

TYPE is a symbol which can take one of the following values:
- Button
- ToggleButton
- slider
- socket
- socket-osr
- cairo
*/

(中略)

  if (EQ(xw->type, Qwebkit_osr)||
      EQ(xw->type, Qsocket_osr)||
      (!NILP (Fget(xw->type, QCxwgir_class)))) {
      block_input();
      xw->widgetwindow_osr = gtk_offscreen_window_new ();

(後略)

emacs 25.1のコードにあるsrc/xwidget.c
https://github.com/emacs-mirror/emacs/tree/emacs-25

DEFUN ("make-xwidget",
       Fmake_xwidget, Smake_xwidget,
       5, 6, 0,
       doc: /* Make an xwidget of TYPE.
If BUFFER is nil, use the current buffer.
If BUFFER is a string and no such buffer exists, create it.
TYPE is a symbol which can take one of the following values:

- webkit

(中略)

  if (EQ (xw->type, Qwebkit))
    {
      block_input ();
      xw->widgetwindow_osr = gtk_offscreen_window_new ();

(後略)

記事としてまとめるために、もう一度ソース読んでたら、冒頭のコメントにばっちり書いてあったorz

ひさしぶりにCのソースを読んだせいで、いきなりコードの方を読むという冒険をしてしまったのが敗因です。

まとめ

  • emacs 25.1でXwidgetがマージされて、ネイティブウィジェットがバッファに表示されるようになった
  • マージはされたが、同じものがマージされたわけではないのでできることはかなり違う
  • ウィジェットを操作(ボタンならクリック、スライダーなら移動)したときに着火されるイベントがわからないと単に表示しておしまいなので、今後はその辺を調べたい。
    • 本当は、鬼軍曹.elGUIで、このキーを実行しろ、と表示するようなelispを書いてみたかった

明日4日目はinoueyuworksさんの「tabulated list 的な UI を量産するために」の予定です。楽しみですね。

補足

emacs25.1ではemacs inside emacsが実現できないかというとそうではなくて、jslinuxを開けばいいよ、とやさしい人がredditで回答してました。(なんかredditへのリンクを貼ると記事を保存できないので単なるテキストだけ残しておきます)

www.reddit.com/r/emacs/comments/4srze9/watching_youtube_inside_emacs_25/d5bvl4f/