Twitter の API リファレンスを久しぶりに見たら、 Application-only authenticationとかいうのを発見。 特定のユーザと関連付けられない代わりに、普通に認証するより制限が緩いみたい。 3月に追加されてたらしい。
知らなかった・・・。 最近API叩いてなかったからな・・・。
便利そうなので、Python用のTwitterライブラリであるTweepyから使ってみた。
AuthHandler Tweepy用のAuthHandler。 認証部分は TwitterのApplication-only authenticationを試してみた のページからほぼコピペ。
import tweepy import urllib import urllib2 import base64 import json class AppAuthHandler(tweepy.auth.AuthHandler): TOKEN_URL = 'https://api.twitter.com/oauth2/token' def __init__(self, consumer_key, consumer_secret): token_credential = urllib.quote(consumer_key) + ':' + urllib.quote(consumer_secret) credential = base64.b64encode(token_credential) value = {'grant_type': 'client_credentials'} data = urllib.urlencode(value) req = urllib2.Request(self.TOKEN_URL) req.add_header('Authorization', 'Basic ' + credential) req.add_header('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8') response = urllib2.urlopen(req, data) json_response = json.loads(response.read()) self.
先日、社内 ISUCON(良い感じにスピードアップコンテスト) に参加してきました。 Livedoorで開催されたISUCONのミニ版で、 Webアプリをひたすら高速化するコンテストです。
高速化の対象はNoPaste。 テキストを共有するWebアプリです。 テキストの投稿・投稿の閲覧・投稿にスターをつける の3つの動作ができる簡単なアプリです。
新卒 vs 先輩ということで、それぞれ4チームが参戦。 チームは二人一組で僕は @Maco_Tasu くんと一緒でした。 @Maco_Tasuくんのブログも参照。
Recent Posts 生成クエリの高速化 高速化前のアプリのベンチマークの結果、スコアは77(≒1分あたりの捌いたリクエスト数)。 何も考えずにデータベースの全行を舐めるクエリを書いていたので、まあ、妥当なスコアですね。
重いのはサイドバーに表示される Recent Posts。 Recent Posts は表示回数が多く、 複数の行、複数のテーブルへのアクセスが発生するため、 きっとここがボトルネックになるだろうと予測してました。 そこで最初にこの部分を解決することにしました。
とりあえずインデックスを張る クエリを修正してアクセスする行を最小化 スターのカウントした結果をテーブルに格納 オリジナルのデータベース構成では、スターした回数だけ行が増えてました 必要なのは投稿ごとのスター数なので、独立したテーブルに この時点で早くも重大なバグを組み込んでしまったことに、この時はまだ気がついていなかった・・・ nginxによる静的ファイル配信 僕がクエリをいじっている間、@Maco_Tasuくんには サーバの設定をお願いしました。
ログの様子を眺めてみると、cssとかjsとかの静的ファイルが結構な量ありました。 最初のスクリプトでは静的ファイルの配信もアプリでやってたので、 これをnginxを使って配信するように変更。 その他のリクエストはリバースプロキシを設定してアプリに投げます。
Starlet と Server::Starter リバースプロキシを設定する際にアプリの起動スクリプトを編集する必要があったので、 ついでに起動時の設定を色々変更。 PSGI実行のStarletというのが速いと聞いてこれを採用。 Starlet使い方調べてたら、Server::Starterを使った例が出てきたので一緒にインストール。 ワーカーの数の数は適当に10個にしました。
ここで2回目のベンチマークを実行。 スコア1300程度で、その時点のトップ!
SSIを使ったサイドバーの埋め込み お昼を挟んで、さらなる高速化を目指します。
topコマンドを眺めているとPerlで作ったアプリの負荷が大きい。 ほとんどテンプレートエンジンを呼び出しているだけの単純なコードなので、 ここを高速化するのは面倒くさい。 そこで、前段のnginxでキャッシュする作戦を採用することにしました。
もっともキャッシュが有効なのはサイドバーだろうと予想。 クエリの最適化をしたとは言え、サイドバーには100件程度の投稿が表示されるので、 クエリ実行にもレンダリングにも時間がかかるはず。 さらにすべてのページでサイドバーは共有できるので、大幅な高速化が期待できるはずです。
過去のISUCONの記事にSSI(Server Side Include)を使った例があったのを思い出し、 これを使ってサイドバーのみキャッシュ、nginx内でサイドバーを埋め込むように。
僕が SSIのタグ埋め込み、 @Maco_Tasu くんにnginxのキャッシュ設定を行ってもらうという役割分担で作業を再開しました。
emacsを使って編集している最中にシェル操作をしたくなって, C-z を押してバックグラウンドにしてシェル操作. その後,emacsに戻ってくるには fg コマンドを打つ必要があるんだけど, 間違えてもう一回 emacs を新しく立ち上げるというミスを何度もやってしまう・・・.
これに対し,猫型さんが複数起動しようとすると警告を出してくれるようにしてくれました. (出、出〜〜〜〜wwww emacsをふたつ以上実行奴〜〜〜〜www)
警告してくれるのはありがたいんだけど, これだとシェル操作中に別のファイルの編集をしたいと思っても,警告が返ってくるだけ. emacs をフォアグラウンドに出して,ファイルの指定をやり直さなきゃいけない. 僕はファイルの編集をしたいんだ!! わかったから早く編集させろ!!!
emacsclient 単なる警告じゃなくて, 「裏で動いていたemacsを復帰させ,新しいバッファを開く」 ところまで自動的にやってくれると嬉しいですね.
まず,emacs をデーモンモードで起動しておきます.
emacs --daemon emacsclient コマンドでファイルを開くと, emacs デーモンさんが新しいバッファで開いてくれます. オプションに -nw を指定しておくと現在の端末で閲覧編集することができます.
emacsclient -nw hoge.txt 終了するにはC-x 5 0. C-x C-cでも終了できるけど, デーモンにバッファが残ってしまうみたい.
aオプションでemacs デーモンが起動してないときに 編集に使うエディタを指定できる. 空っぽにしておくと,emacs をデーモンモードで起動してくれる.
emacsclient -nw -a '' hoge.txt emacs デーモンを終了させるのは以下のコマンド.
emacsclient -e '(kill-emacs)' emacsclient に対して alias を作っておけば, 複数起動かどうか意識せずに使えますね.
alias emacs='emacsclient -nw -a ""' 参考 emacsclientを使おう emacsclient の使い方の種類と、便利な使い方 emacsclientを終了する方法
LaTeXで書いた文章を電子書籍にしたくなったので, LaTeX2EPUBを使ってみました.
LaTeX2EPUBはLaTeXMLとReVIEWに依存しているようなので, それぞれインストールしていきます. あと,数式の変換とかにLaTeXを使っているので別途用意する必要あり. いろんなディストリビューションがあるけど, ここでは TeX Live 2012 を使いました.
LaTeXML のインストール LaTeXMLはLaTeXの文章をXML形式に変換するソフト. そこからさらにXSLTを使ってXHTMLへ変換できる. ドキュメントに従って 依存するライブラリをインストール.
perl -MCPAN -e shell cpan> install DB_File, Parse::RecDescent, File::Which cpan> install XML::LibXML, XML::LibXSLT ドキュメントが少し古いらしく,これだけでは不十分だった. 追加でParse::RecDescentとImage::Magickもインストールしておく.
cpan> install Parse::RecDescent cpan> quit yum install ImageMagick-perl 後はソースを取ってきてmakeするだけ. 現時点での最新版0.7.0をインストールした.
wget http://dlmf.nist.gov/LaTeXML/releases/LaTeXML-0.7.0.tar.gz tar zxvf LaTeXML-0.7.0.tar.gz cd LaTeXML-0.7.0 perl Makefile.PL make make test make install ReVIEW のインストール ReVIEWは簡単なマークアップ言語で書かれたテキストから PDFやEPUBを作成するためのスクリプトです. このなかのEPUB作成機能に依存しているようなのでインストールしておきます. ReVIEWはgemで簡単インストール.
gem install review LaTeX2EPUB のインストール LaTeX2EPUB本体をインストール. 本家の日本語化対応が少し不十分だったので 改造版を上げといた. これをダウンロードしてパスの通ったところに置けばインストール完了.
Amazon Web Services(AWS)でEC2でも使ってみようかと, 登録を試みました.
が,しかし,電話認証の段階で何度やってもシステムエラー・・・.
An Error Has Occured システムエラー 電話確認要求を処理できません。後でもう一度お試しください。
こういう時は,とりあえずエラーメッセージでググってみましょう. なんだかそれっぽい記事が見つかりました.
AWSアカウント開設で”電話確認要求を処理できません。後でもう一度お試しください。”と怒られ続けた Amazon Developer Forums: 電話による身元確認でエラー発生 どうやら,登録時に入力した「支払い方法」と「アドレス情報」が正しく反映されていないことが原因のようです.
アカウントの管理 画面から,「支払い方法」を選び,クレジットカードや請求先を記入します. アドレス情報は「登録内容の変更」から変更可能です.
AWSをはじめてみたというエントリだけど, 実はじょりぼっとの「買うべき?」機能を実装するために, AWSのProduct Advertising APIを前々から使っていたのでした. このAPI使うだけなら支払い方法などの入力は不要だったので, 必要最低限の情報しか入力していませんでした. 住所とかの入力もしなかったのですが, 自分が確認したときはアドレス情報の国設定が何故かアメリカになってました. これのせいですかね?
詳しい原因はよくわかりませんが,とりあえず,「支払い方法」と「登録内容の変更」の全項目を正しく入力したら認証が出来ました. 1年は無料でいろいろ遊べるらしいので,何か動かして遊んでみましょう.
じょりぼっとが初めてつぶやいてから 今日でちょうど一年となりました.
突然の凍結,74回にも及ぶバルスなどなどを乗り越え, 今日まで生き延びられたことを嬉しく思います.
ちなみに一番最初のツイートはこんなのでした.
自分の教科にしましたというわけで終わりー。どっちも一部の断面図
— 狼とボット (@JO_RI_bot) 2012年1月22日 学食メニュー じょりぼっとが一周年を迎えるということは, 起動当初から続けてきた学食メニュー表示機能も一周年ということです. 一年分のメニューはこちらにストックしてあります. どんなメニューが出されることが多いのか,簡単な統計を取って見ました.
1食昼食A定 回鍋肉 13 鶏肉と味噌漬け焼き 9 チキン唐揚げ 8 豚肉キムチ炒め 7 ちきんカツ 7 チキン唐揚げ<スパイシーカレー> 7 豚肉朝鮮焼き 7 焼肉とピーマン肉詰めフライ 7 チキンソテーさわやかソース 7 チキンマスタード焼き 7 鶏肉キムチ焼き 7 チキンピザソース焼 7 1食夕食A定 チキンピザソース焼 13 酢豚 11 豚カツ 9 チキンソテーさわやかソース 9 グリルドチキンイタリア風 9 鶏肉と味噌漬け焼き 8 エッグ焼肉 8 Bigメンチ 8 焼肉と春巻き 8 チキンステーキタルタルソース 8 1食昼食B定 筑前煮 16 いりどり 13 八宝菜 12 白身魚フライの卵とじ 11 白身魚のピリピリ漬け 10 鯖の生姜焼き 9 白身魚フライチーズ焼き 9 うずら卵と野菜の五目煮 8 鶏肉の酢豚風 8 シューマイの中華風旨煮 8 チキンブラウンソース煮 8 サーモンシチュー 8 アジフライとツナサラダ 8 白身魚の磯辺揚げ 8 1食夕食B定 すき焼き風旨煮 19 うずら卵と野菜の五目煮 13 スペイン風オムレツとコロッケ 13 ピザ卵とコロッケ 12 鶏肉と野菜の七味炒め 12 鮭の野菜あんかけ 11 鶏肉とヤングコーンの豆板醤炒め 10 アジフライとツナサラダ 9 チキンブラウンソース煮 9 白身魚のピリピリ漬け 9 1食昼食セット オムライス 16 五目あんかけ焼きそば 13 鮭チャーハン 12 ねぎトロ丼 12 鶏肉ときのこのチャーハン 11 トルコライス 11 三色丼 9 鶏の照り焼き丼 9 ビビンバ丼 9 親子丼 9 麻婆丼 9 1食夕食セット キーマカレー 13 ビビンバ丼 10 肉たれうどんとぶっ玉丼 10 海の幸うどん 9 すき焼き丼 8 肉うどんとカレーライス 8 ねぎトロ丼 8 イタリア風チキンカツ丼 8 鶏の照り焼き丼 6 とろろそばとミニカツ丼 6 鮭茶漬け 6 1食昼食単品 鶏肉とブロッコリー炒め 16 さつま汁 15 揚ギョーザ 13 のっぺ 13 イカ野菜カツ 13 揚げ豆腐の旨煮 13 かぼちゃのそぼろあんかけ 12 ハムチーズサンドフライ 12 エビ風味グラタンコロッケ 12 鶏肉とタケノコの旨煮 12 ブロッコリーとカリフラワーの炒め 12 茄子の中華風旨煮 12 豚肉と野菜の煮込み 12 卵と玉ねぎのソテー 12 1食夕食単品 鶏肉とチーズ焼き 17 レバニラ炒め 15 豆腐きのこあんかけ 13 ゆで卵 13 ちくわの二色揚げ 12 鶏肉と里芋の煮物 11 蒸シューマイ 11 けんちん汁 11 五目金平 11 五目肉じゃが 10 シューマイのカレー揚げ 10 ブロッコリーとカリフラワーの炒め 10 2食お昼ごはん定食 ピーマン肉詰めフライ 13 ちきんチーズ焼き 13 ハッシュドビーフ 12 鶏肉のピリカラ味噌焼き 10 カレーコロッケ 8 春巻き 7 野菜コロッケ 7 鰹の刺し丼 7 ちきんカツ 7 豚玉丼 7 レッドホットチキン 7 きじ焼き丼 7 ちきん南蛮漬け 7 ハンバーグ 7 海老グラタンコロッケ 7 2食晩御飯定食 545円定食 34 545円丼 16 フライアンドフライ 13 ちきん南蛮 11 新潟タレカツどん 11 中華角煮丼 10 ねぎトロ丼 9 スパイシードライカレー 9 レッドほっとマヨ 9 545丼 8 2食に関しては,集計か3月からなのでまだ一年たっていません. それにしても圧倒的な545円定食の出現頻度. 結局何が食べられるのか全くわからないのですが・・・.
SSHには標準でTCPのトンネリング機能は付いているのですが, UDPはトンネリングしてくれません. なんとかできないものかと試行錯誤してみました.
TCP をトンネル TCPのトンネリングの復習から. 以下のコマンドでクライアントの8080番ポートを,リモートの80番ポートに転送することができます.
ssh -L 8080:localhost:80 remote SOCKS proxyとして動作させることも出来ます. ブラウザのプロキシとして設定すれば,リモートのサーバがすべての通信を中継してくれます.
ssh -D 8080 remote UDP をトンネル NetCatを使うと TCP/UDP の通信内容と標準入出力をつなげることが出来るらしいです. これを使って,クライアント側で UDP サーバを立て,その通信内容をSSH経由でリモートの UDP クライアントに送ってあげます. 最後にリモートからクライアント側へのパケットを名前付きパイプで転送してあげればトンネル完成です.
mkfifo tunnel nc -ul 8080 < tunnel | ssh remote nc -u localhost 8080 > tunnel Mosh をトンネル なんでこんなことをしようと思ったかというと,Moshをファイヤーウォール越しに使いたかったから. MoshはUDPで通信しているので,SSHしか通らない環境では使えません. そこでUDPをSSHでトンネリングしてできないかとやって見ました. セッションの確立にSSHも使っているので,以下のようにして Mosh用のUDPトンネルと SSH用のTCPトンネルを作ります.
mkfifo tunnel nc -ul 60000 < tunnel | ssh -L 10000:localhost:22 remote nc -u localhost 60000 > tunnel & mosh -p 60000 --ssh="ssh -p 10000" localhost 外部からのSSH通信が遅かったので,Moshのローカルエコーでなんとかならないかと挑戦してみました. 実際の効果は未確認.またあとで試してみます.
「WaveZutaZutaというおもちゃを書いている話」 という記事を見ていたら,誰かがツイッターで 「いっちーがJavaScriptに移植してくれる」と発言.
あ,はい.やってみましょう.
どんな感じのものなの? 音声ファイルをテキトーに切り貼りできるライブラリです. WaveZutaZutaJSにブラウザで実行出来るサンプルを置いたので 実際試してみるのが一番わかりやすいと思います. 適当な音声ファイルをドラッグ&ドロップして,playボタンを押すと音が流れるので,いろいろ遊んでみてください.
テキストボックスには楽譜が書かれています. 楽譜の書き方は「WaveZutaZutaというおもちゃを書いている話」 と同じです.
ちなみに、楽譜ファイルの読み方、書き方ですが、aからzまでの文字それぞれにずたずたにされたwaveファイルの"破片"がアサインされていて、-は音をのばす(タイ)を意味し、0は休符を意味します。*を指定すると、a-zのうちどれかをランダムで鳴らします。1文字が64分音符ひとつ分の長さです。空白文字は無視されます。
使い方 リポジトリの WaveZutaZutaJS.js がライブラリの本体です. 次のように使います.
var data = new ArrayBuffer(); // ずたずたにしたい音声データを入れておく var context = new AudioContext(); var zuta = new WaveZutaZuta(context); zuta.onSuccess = function(self, source) { // 元の音声の先頭5秒から3秒間流す zuta.setNote('a', 5); var node = zuta.getAudioNode([{sound: 'a': length: 3}]); node.connect(context.destination); }; zuta.loadAudio(data); data には入力音声のバイナリデータを入れておきます. 形式はブラウザが対応していれば何でもOKです. Chromeなら wav, mp3, mp4 など,メジャーな形式はたいてい読めると思います.
getAudioNodeで返ってくるのは AudioNode なので,WaveZutzZutaJS の出力にさらにエフェクトをかけることができます. 例えば,次のコードで周波数フィルタを通すことができます.
var data = new ArrayBuffer(); // ずたずたにしたい音声データを入れておく var context = new AudioContext(); var zuta = new WaveZutaZuta(context); zuta.
この記事はTeX & LaTeX Advent Calendarの傘下記事です. 15日はk16.shikanoさんの「TeX がむかついたので実装したけど挫折してる話」, 17日は@egtraさんの「LCDF TypetoolsでOpenTypeフォントを使う(DVIPDFMXで)」です.
neruko3114が参加しているのを見てなんだか楽しそうだったで参加してみました. とはいってもネタも思いつかなったので,過去に作ったものをTeXに移植してみました. ターゲットはTinySegmenter. 以前作ったTinySegmenterMakerでLaTeXを出力できるようになったよ!
使ってみる TinySegmenterMakerのレポジトリをダウンロードするなりgit cloneするなりして 落としてきます. レポジトリに入っているのはモデルファイルとスクリプトだけです. これらを使ってTeXのスタイルファイルを作ります.
$ cd /path/to/TinySegmenterMaker/ $ ./maker tex < RWCP.model カレントディレクトリにtinysegmenter.styができます. TeX から見えるところにおいておきましょう. これを使うソースコードは次のようになります.
\documentclass{jarticle} \usepackage{tinysegmenter} \begin{document} \TinySegmenter{-}{私の名前は中野です} \end{document} platexで処理するとこんな感じに表示されるはず.
私-の-名前-は-中野-です 仕組み TinySegmeneterは元の文章の一部を切り取ってハッシュに入れる動作をしている. でも,LaTeXにはハッシュみたいなデータ構造がないのでコントロールシーケンスで代用. \@ifundefinedで有無を確認し,\csname\endcsnameで置き換え. コントロールシーケンスの一部に日本語を使わないといけないので,日本語LaTeX環境でしか動かない. ただ,一部句点などの扱いが違う?よくわからない.
あとは,文字種の取得が必要なんだけど,ここでも同じことをしてます. すべてのアルファベット・ひらがな・カタカナ・数字について,その文字種をベタ書き. それ以外は全部漢字扱い. そのため,それ以外の文字を使うとオリジナルとは違う結果になるかも.
最後は足し算.これはカウンタを使えば簡単ですね.
応用編 TinySegmenterMakerでは自由にモデルを差し替えることができます. 以前JavaScript版のTinySegmenterを使って, 聞こえますか…自動生成…してみた…よ… ということをしてみました. LaTeXだってできるはず.
聞こえますか… に心に呼びかけるためのモデルファイルが含まれています. これをダウンロードして読み込ませます.
$ ./maker tex < model これを自分のドキュメントに読み込ませてみます.
\documentclass{jarticle} \usepackage{tinysegmenter} \begin{document} (…\TinySegmenter{…}{聞こえますか聞こえますかあなたの心に直接語りかけています}…) \end{document} 私の声が聞こえましたか・・・?
日本語の文章をコンピュータで色々いじるときに, 必ずと言っていいほどよく使うのが形態素解析器. スペースなどの明示的な区切りの無い日本語を単語に分割してくれるツールです. 中でもMeCabが非常に有名で,さまざまなところで使われています.
MeCabはいろいろな言語から呼び出すことができます. 自然言語処理の分野ではPythonが人気のようですね.僕も使っています. しかし,MeCabをPythonから使う場合,注意する点がいくつかあります. そこにハマっている後輩を見かけたので,文章として残しておくことにします. Python2系が対象です(3系はよくわからない). 注意するのは以下の二点です.
MeCabに渡す文字列はencode,戻ってきた文字列はdecodeする MeCabに渡した文字列は必ず変数に入れておく EncodeとDecode Python2系の文字列には,バイト列として扱われる文字列(str)と,Unicodeで表現された文字列(unicode)があります. 日本語を扱う場合,strだといろいろ問題があるので,特に理由がなければunicodeを使うべきです. しかし,MeCabはstrしか受け付けません. そこでMeCabに渡す直前・直後でencode・decodeするようにします.
import MeCab tagger = MeCab.tagger('-Owakati') text = u'MeCabで遊んでみよう!' result = tagger.parse(text) # エラー! encoded_text = text.encode('utf-8') # encodeが必要 encoded_result = tagger.parse(text) result = result.decode('utf-8') # 必ずdecode 'utf-8'の部分は辞書の文字コードに合わせて適宜書き換えてください. デフォルトはeuc-jpですが,utf-8の方が幸せになれると思います.
必ず変数に入れる 次にMeCabの作ったノードに直接アクセスして,品詞情報などを取ってくることを考えます. 適当に書いてみるとこんな感じでしょうか.
import MeCab tagger = MeCab.tagger('') text = u'MeCabで遊んでみよう!' node = tagger.parseToNode(text.encode('utf-8')) while node: #printはstrを渡す必要があるのでdecodeは不要 print node.surface + '\t' + node.feature node = node.