JavaScriptでn-gram

素朴に書いてみようと思って書きましたよ。のメモ。

var ngram = function(words, n) {
  var i;
  var grams = [];
  for(i=0; i<=words.length-n; i++) {
    grams.push(words.substr(i, n).toLowerCase());
  }
  return grams;
}

var text = "Hi. 本日は晴天なり。";
console.log(ngram(text,2));
console.log(ngram(text,3));

実行すると、BigramとTrigramの実行結果が得られます。

[ 'hi', 'i.', '. ', ' 本', '本日', '日は', 'は晴', '晴天', '天な', 'なり', 'り。' ]
[ 'hi.', 'i. ', '. 本', ' 本日', '本日は', '日は晴', 'は晴天', '晴天な', '天なり', 'なり。' ]

ロジックゲートをnode.jsでシミュレーションする

Rubyで2の補数の話題ぐらいから6年ぶり*1のビット演算の話題。

ロジックゲートをシミュレーションするg8というライブラリがあったので少し触ってみました。

サンプル見ればそのままなのですが、一応手元でも試してみました。

なぜか「ぬ」という日本語名がプロジェクト名。

var g8 = require('g8');
var a = g8.word(8);
var b = g8.word(8);
console.log("a=" + a('11110000', '1'));
console.log("b=" + b('00001111', '1'));
console.log("---");
console.log("a or b = " + g8.or(a('00000000', '0'), b('00000000', '0')));
console.log("not b  = " + g8.not(b('00000000', '0')));
a=11110000
b=00001111
---
a or b = 11111111
not b  = 11110000

これを利用して、10bit CPUの実装も行われていて興味深い。

最近コードを書いていてもビットの気持ちを忘れているなと感じたので時々触って思い出そうと思う。

*1:多分...ちゃんと振り返ってない...

evac – Node.js based simple aggregator

evacというシンプルなアグリゲーターを作りました。個人用途で作っていたのですが、そこそこ形になったのでnpmで公開しています。

NPM

よくあるアグリゲータの実装と同様に入力、加工、出力をJSONファイルで定義することでアグリゲーションすることができます。

例えば自分の場合は以下の様な使い方をしています。

  • ブログの記事に更新があれば、gmail通知
  • 社内SNSのスケジュール機能で用意されているiCalファイルを読んで、一時間以内に予定があれば仕事で利用しているMac上にgrowl通知
  • DBに接続して数値を取り、dashingAPIに向けてPOSTする
  • あるサービスのwebページをスクレイピングしてKPIにしているパラメータを抽出してIRCに通知
  • RSSを走査し特定の文字列があればIRCに通知

などなど、いままでであれば小物スクリプト書いて動かしたりしていたものを置き換えすることができました。

自分以外だと、街に詳しい@

  • iTunesConnectから自分が管理しているiPhoneアプリのダウンロード数を取得してIRCに通知

といった形でも利用してくれています。

実際の例として、例えば予定通知の例だと以下の様な設定ファイルを準備します。

{
"in": {
"ical": {
"url": "http://****.********.jp/calendar/ical/*****.ics",
"within": 1
}
},
"filter": {
"through": {}
},
"out": {
"notice": {
"type": "growl",
"title": "予定の通知"
}
}
}

これを定期的にevacで呼び出してやると、呼び出し時から一時間以内に予定があれば…

f:id:hideack:20141114092941g:plain

の様にgrowl通知できます。当たり前ですがOutput変えれば、何か予定があればIRC通知させたり、Yoさせたり、Pushbulletでプッシュ通知させたりもできます。

出力用のプラグインとしてYoやPushbulletを利用して出力ができるようにしたので私が以前作っていたTOKYOAMEDAYOの様なbotも比較的簡単に作れるのではないかと思います。

このあたりの実装しているプラグインは以下のページに簡単にまとめてあります。*1

基本、cronで定期的に回す等々が使い方かなと思うのですが、evac自身にもcron的な動きができる様に実装がしてあるので

[
{"*/10 * * * *": "/home/hideack/recipe/rss.js"},
{"0 18 * * *": "/home/hideack/recipe/news.js"}
]

といった具合に設定ファイルを準備してあげることで一般的なcron書式に従って、evacを起動させることができます。foreverで永続化する等をしてやるとよいかもしれません。

設定ファイルのフォーマットやプログラムの作り自体も荒削りなところがあるのですが、まずは自分の周りが少し便利になったのでより使いやすくなる様に対応進めていきたいと思います。

蛇足

evacは脱出という意で情報をあるところからあるところに飛ばす的な意でつけました。

*1:簡単すぎますね...

日本橋へ魚を食べに行く

入院していた友達が退院したということで、回復祝いにお魚を食べに行った。

日本橋 墨之栄
〒103-0022 東京都中央区日本橋室町2-2-1 COREDO室町1 2F
5,000円(平均)1,000円(ランチ平均)

魚を一匹まるごと頼んで、好きな調理方法で調理してもらってそれで食べるというスタイルなのだけど、大きめの魚を1匹頼んで刺し身、天ぷら、酒蒸しにしてもらったところとても満足だった。

単品のメニューもあるのだけど、魚を指定して店員さんがオススメする調理法を聞きながら料理してもらうのがこの店では正解な気がする。

食べるのに夢中で食べたものの写真を取らなかった...。日本酒の種類も多くて、魚料理によくあって大変よかった。また是非行ってみたい。


全然話は変わるが、夜見る日本橋麒麟は格好良かった。

PushbulletのAPI経由でPush通知する

Pushbullet というサービスのAPIを使ってPushbulletがインストールされた端末(iPhone, Android, PCブラウザ) に向けてPush通知する術をあれこれ調べた際のメモです。

そもそもPushbulletは先に書いた様なPushbulletのクライアントアプリがインストールされた端末間で相互にテキストや画像を相互にやり取りできるサービスです。Googleアカウントのみで利用することができます。

Chrome Web Store - Pushbullet Chrome Web Store - Pushbullet このエントリーをはてなブックマークに追加

Pushbullet - Google Play の Android アプリ Pushbullet - Google Play の Android アプリ このエントリーをはてなブックマークに追加

Pushbullet on the App Store on iTunes Pushbullet on the App Store on iTunes このエントリーをはてなブックマークに追加

これらを端末に導入することで導入した端末間で例えば、

  • iPhoneで撮影した画像をPC側へ送る
  • PCのChromeブラウザでメモしたURLをiPhoneに送る

といったことが簡単にできてとても便利なのですが、APIが用意されているのでプログラムを作成して操作することもできます。

まず、APIのアクセストークンを取得します。Pushbulletにログインして、右上のアカウント設定(Account Settings)を選ぶとAPIAccess Tokenが表示されるのでこちらを控えます。

で、これを利用してAPIを呼び出せばPushbullet経由で任意の情報をPushbulletが導入された端末にPushすることができます。素朴なHTTP APIなので各言語向けにライブラリが用意しているのでそちらを利用すると良いかと思います。

以下、node.jsの場合、npmに pushbullet というパッケージがあるのでそちらを利用すると楽です。

NPM

$ npm install pushbullet

を行った後、以下の様な実装でPushbullet導入端末にプッシュすることができます。

第1引数にPushbulletで使ったGoogleアカウントのメールアドレスを渡すとPushbulletの自身のアカウントに紐もづいている全てにPush、Pushbulletで割り当てられているdevice ID を渡すと特定の端末のみにPushできます。

var PushBullet = require('pushbullet');
var pusher = new PushBullet("*******");   // Access Token
pusher.note("****@gmail.com", "test", "test body", function(error, response) {
// snip
});

とするだけで、例えばiPhoneであれば、

といった具合にPush通知がされて、開くと、

といった具合で、pushした本文も含めて表示されます。他にも通知の種類があって、

pusher.link("****@gmail.com", "blog", "http://hideack.hatenablog.com", function(error, response) {});

とすると、リンクを直接通知することができて、このPush通知を開くと

と、Pushbulletアプリ内のブラウザで即座に該当するページが開かせることができたり、

pusher.list("*****@gmail.com", "list", ["foo", "bar", "hoge"], function(error, response) {});

とすると、以下の様なチェックリストを送ることができます。

Pushbulletで用意されているiPhone/Android向けアプリやブラウザ拡張でも素朴に便利なのですが、エンジニアの方であればAPI経由で操作することでいろいろ拡張できそうですね。というお話でした。

Jekyllで記事中にレンダリングされたMarkdownを差し込む

GitHub Pages を利用して静的なページを持つサイトを作るときにJekyllを利用していて、作成したページ中に別ファイルで書いたMarkdownファイルを流し込んでHTMLを作成したいと思ってあれこれ調べたのでメモ。

Jekyllのテンプレートのタグに include があるので、

.
├── _incldes
│   └ foo.md

といった具合に _includes というディレクトリを新しく掘ってその中にMarkdownのファイルを置いて

{% include foo.md %}

と書いたら表示はされるのだけど、Markdownファイルがそのまま表示されてしまった。
あれこれ調べてみると、

{% capture foo %} {% include foo.md %} {% endcapture %} {{ foo | markdownify }}

といった書き方で解決できた。中身的には

  • fooという変数を定義開始
  • 変数に _include に置かれたfoo.mdの内容を入れる
  • fooという変数の定義終了
  • fooの中身をMarkdownからHTMLに変換

といった意になると理解した。というメモエントリでした。

node.jsで定期処理をさせる

npmにあるcronというモジュールを使うとサーバーでよく扱うcronと同様にスケジュールを指定して定期的な処理を書くことができる。

var CronJob = require('cron').CronJob;
var job = new CronJob({
cronTime: "*/5 * * * * *",
onTick: function() {
console.log("5sec!");
},
start: true
});

と、書くことで5秒毎に 5sec! と表示できます。

魚を食べる

大学の同級生の入院お見舞いへ行って、お見舞いメンバで東京駅近くでお魚を食べていました。

http://photos-c.ak.instagram.com/hphotos-ak-xaf1/10729197_309779729214082_1075794144_n.jpg

煮付け頼んだら普段よりデカイと店員さんが言いながら持ったキンメダイの様子です。

友達が退院したらみんなで今度、また何か食べに行こう。

Dashingを使って指標を表示させるダッシュボードを作る

業務で見ているパラメータ(KPI的なもの)をダッシュボード的な体で表示させたいなと思ってあれこれ調べると
DashingというGemを見つけてこれを使うとパラメータを常時表示させるものをかなりカジュアルに
作れたのでご紹介。

デモはここで確認できます。Herokuの上で動いてますね。

DashingShopifyが作っていてShopify自体もオフィスでこれを利用して
パラメータをTV等に表示させているとのこと。

インストール

$ gem install dashing

dashing コマンドを使える様にします。

ひな形を作成

作成するダッシュボードのひな形を作成します。

$ dashing new test
create  test
create  test/.gitignore
create  test/Gemfile
create  test/README.md
(snip)
create  test/widgets/text/text.coffee
create  test/widgets/text/text.html
create  test/widgets/text/text.scss

といった具合で指定した名前でディレクリが掘られてそれ以下に必要なファイルが設置されます。

とりあえず起動してみる

作成したディレクトリに移動してまずはbundle installします。

$ cd test
$ bundle install --path vendor/bundles
(snip)

次にダッシュボードを起動します。*1

$ bundle exec dashing start
Thin web server (v1.6.3 codename Protein Powder)
Maximum connections set to 1024
Listening on 0.0.0.0:3030, CTRL+C to stop

で、http://localhost:3030/ でダッシュボードを確認することができます。

停止は $ bundle exec dashing stop で停止できます。

また、上記で起動するとログを標準出力に出す形で起動するので、

$ bundle exec dashing start -d

とすることで、デーモン化することができます。

ダッシュボードを新規に作成する

全く新しくダッシュボードを作るときには dashboard ディレクトリ以下に任意のerbテンプレートを設置することで
新規に作成することができます。

例えば dashboard/test.erb に以下のテンプレートを書いてみます。

<% content_for :title do %>test<% end %>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
<div data-id="welcome" data-view="Text" data-title="Text widget" data-text="Dashingテスト" data-moreinfo="テストだよー"></div>
</li>
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="test-data" data-view="Number" data-title="売上" data-moreinfo="テストです" data-prefix="¥"></div>
</li>
<center><div style="font-size: 12px">Try this: curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "text": "Hey, Look what I can do!" }' \http://<%=request.host%>:<%=request.port%>/widgets/welcome</div></center>
</div>

これを置いてアクセスをすると以下の様なダッシュボードが http://localhost:3030/test で表示できる様になります。

ここで、実際にダッシュボードへ数字を入れるには、

  • jobs ディレクトリ以下に数値をダッシュボードに送信するRubyスクリプトを置く
  • ダッシュボードに設けられるAPIにPOSTリクエストを送る

の2つの方法があるのですが、後者であれば既存のサービスで動いているスクリプト等とも相性が良いのでそちらを試してみることにします。

先のerbテンプレートのサンプルで「売上」というウイジットを表示させるために

<div data-id="test-data" data-view="Number" data-title="売上" data-moreinfo="テストです" data-prefix="¥"></div>

というタグを書いていて、

  • data-view
    • widgets ディレクトリ以下にあるウイジット実装が対応
    • ウイジットとはサンプルにあった数字を表示させたりグラフを表示させたりするものが相当
  • data-id
    • ウイジットをAPIやjobs以下に置かれるスクリプトで更新する際に一意性を識別するためのID

となっています。なので、今回のNumberというウイジットであれば以下の様なcurlコマンドを叩くと該当の
ウイジットの数値を更新することができます。

$ curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "current":100}' http://localhost:3030/widgets/test-data

上のcurlコマンドを叩くと

更新されます。

今回は Number というウイジットに対して更新をかけるため、current というパラメータをcurlコマンドでPOSTしましたが、このパラメータはウイジットによって異なります。

で、その辺りを簡単に知るには直接 widgets ディレクトリ以下にある各ウイジット毎のCoffee scriptを読むと把握できます。*2


といった具合で、Dashingを利用すると、簡単にダッシュボードパネルを作成することができるのでお勧めです。

こういった形で数値をリアルタイムで確認できる様になると、プロジェクトに関わる全員が現状を把握しやすいのと数字が動いているのをみることで「動いている実感」が沸くのでオススメです。

*1:ちなみにアプリケーションサーバとしてはThinが利用されていいます。

*2:現状、ドキュメントにまとめられていないので恐らくそれしか知るすべがなさそう。シンプルなのですぐ読み取れますが。