bit sized

Just another WordPress.com weblog

2月 2009のアーカイブ

Ubiquityを使って英単語を調べる

2件のコメント

FireFoxのプラグインでUbiquityというのがあります。他のWebサイトの機能をコマンドとして登録して使用できる、User MashUpを可能にするFirefox上の環境です。将来的にはFirefoxのURLバーに実装されるかも知れません(URLをWebのドキュメントがある場所であると考えるのではなく、Web上のリソースに対するリクエストような考えると割と自然な進歩?)。

ブラウザの新境地? Ubiquityが変える衝撃のブラウザ体験 (1/2):
http://www.itmedia.co.jp/enterprise/articles/0808/31/news003.html

まあ、そういうわけでどういうものかちょっと気になって見てみて、最近APIが公開されたiknowという英語学習SNSの単語検索を呼び出すコマンドを作成してみました。

iknow-search

iknow-search

コード

CmdUtils.CreateCommand({
  name: "iknow_search",
  icon: "http://example.com/example.png",
  homepage: "http://example.com/",
  author: { name: "xxxx", email: "xxxxx@gmail.com"},
  license: "GPL",
  description: "search words or pharase in iknow",
  help: "iknow",
  takes: {"input": noun_arb_text},
  preview: function( pblock, input ) {

    var baseUrl = "http://api.iknow.co.jp/items/matching/${word}.${format}";
    var tempUrl = {"word":input.text,"format":"json"}
    var params = {include_sentences:"true"};

    pblock.innerHTML = "";

    jQuery.getJSON(CmdUtils.renderTemplate(baseUrl,tempUrl),params,function(resp){
      jQuery.each(resp,function(i){
        pblock.innerHTML += this.responses[0].text + "<br/>";
        pblock.innerHTML += this.sentences[0].text + "<br/>";
        pblock.innerHTML += this.sentences[0].translations[0].text + "<br/>";
      });
    });

  },
  execute: function(input) {
    var baseUrl ="http://www.iknow.co.jp/items/search?keyword=${QUERY}";
    var tempUrl = {"QUERY":input.text};
    var urlString = CmdUtils.renderTemplate(baseUrl, tempUrl);
    Utils.openUrlInBrowser(urlString);
  }
});

Ubiquityコマンドの作成
Ubiquityコマンド作成の情報は、現状下記のリンクかソースを見るしかないくらい少なく、しかも上記のコマンドはまだプレビューで訳を表示しEnterキーでiKnowのサイトで該当のアイテム検索結果を表示するのみですが、行数の割には用を足しているかと思います。Ubiquity導入後、Command Editorを使用して上記のコードを貼付ければ使用できます。

Labs/Ubiquity/Ubiquity 0.1 Author Tutorial
https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial

上のチュートリアルに載っている事ですが簡単に作り方を説明したいと思います。

CmdUtils.CreateCommand({
  name: "hello-world",
  execute: function() {
    displayMessage( "Hello, World!" );
  }
})

ubiquityコマンドは、cmd_<コマンド名>というfunctionがあればそれを参照するのですが、普通はCmdUtils.CreateCommand()というユーティリティ関数を使用して作成します。上記のコードはその最も単純な例です。

CreateCommandに渡すオブジェクトのnameとexecuteというプロパティに、それぞれコマンド名の文字列と実行する関数を指定します。execute(コマンドの実行)はUbiquityのコンソールにコマンド名を入力しEnterを押した時点で実行されます。displayMessage()を実行すると、MacならGrowl,WindowsならUbiquityのコマンドの下に引数に与えた文字列が表示されます。

Hello-worlddisplay hello world

CmdUtilsにはコマンド作成以外にも、ユーザーがブラウザで選択中の箇所にテキストやHTMLを挿入(setSelection),IPから位置情報を取得(getGeoLocation),文字列のテンプレート処理(renderTemplate)などコマンド作成を楽にする関数が用意されており、これまたドキュメントは少ないのですが、ソースはこちらで見る事ができます。

プレビューの表示
Ubiquityではユーザーの入力に応じて出力されるプレビューウインドウがあり、こちらはCreateCommandに渡すオブジェクトのpreviewプロパティに、HTML文字列か関数を指定する事で実現できます。下記は冒頭のコマンドでのpreview部分です。

preview: function( pblock, input ) {

    var baseUrl = "http://api.iknow.co.jp/items/matching/${word}.${format}";
    var tempUrl = {"word":input.text,"format":"json"}
    var params = {include_sentences:"true"};

    pblock.innerHTML = "";

    jQuery.getJSON(CmdUtils.renderTemplate(baseUrl,tempUrl),params,function(resp){
      jQuery.each(resp,function(i){
        pblock.innerHTML += this.responses[0].text + "<br/>";
        pblock.innerHTML += this.sentences[0].text + "<br/>";
        pblock.innerHTML += this.sentences[0].translations[0].text + "<br/>";
      });
    });

  },.....

previewは第一引数にpreviewエリアに表示するDOM要素を、第二引数にユーザーから渡されるコマンドの引数をとっています。コマンドの引数はtakeプロパティで、どのnoun_typeで取得するか指定できます。

  takes: {"input": noun_arb_text},

引数データの扱い
noun_typeは引数の制約や、コマンドの補完機能(例えば日付データが入力されたら、日付データを引数にとるコマンドをUbiquityがサジェストする)に使用され、下記のようなnoun_typeがあります。また、CmdUtilsを使用してカスタムのnoun_typeを作成する事ができます。

  • noun_type_arb_text
  • noun_type_date
  • noun_type_language
  • noun_type_people
  • noun_type_place
  • noun_type_tab

noun_typeのソースは下記で確認する事ができます
nountypes.js

一方、コマンドの引数としてpreviewやexecute(の第二引数)に渡されるオブジェクトは、下記のようなプロパティを持ちます。

  • inputObject.text // 文字列
  • inputObject.html //タグを含む整形されたHTML
  • inputObject.data // 文字列以外のnoun_typeのデータ
  • inputObject.summary // 長い文字列の要約版

iknow-searchのpreviewで行っているのは、コマンドの引数から(テンプレート機能を使用して)URL文字列を組み立て、JSONでリクエストを取得、preview用のDOMに結果を反映するという一連の処理ですが、uqibuityではjQueryが使用できるため簡単に実装できます。

また同様に、コマンド入力後Enterを押した時に実行されるexecuteでは、Utils.openUrlInBrowser()を使用してブラウザで該当のURL(検索結果ページ)を開くようになっています。

まだまだ発展途上(というかできたばかり)のコンセプトですが、Webの機能をお手軽にコマンドにできるのはこれから重宝しそうです。

追記:Ubiquity のアップデートに合わせて、コードも少し書き換えました

投稿者: t4ku

2月 8, 2009 3:05 pm

Programming, Technology への投稿

Processingでグラフ

コメントなし

前から少し気になっていたProcessingという言語について、ちょうど本屋におもしろそうなオライリー本が出ていたので買ってみました。

ビジュアライジング・データ ―Processingによる情報視覚化手法

簡単な例としてグラフの作成があったので、自分でも日本の人口統計を使ってグラフを書いてみました。

Population growth in Japan

Population growth in Japan

  1. FloatTable data;
  2. PFont plotFont;
  3. float plotX1,plotY1;
  4. float plotX2,plotY2;
  5. float labelX,labelY;
  6. float dataAreaWidth;
  7. float dataAreaHeight;
  8. final float dataOffsetY = 30;
  9. float volumnInterval = 10000;
  10. float dataCeil;
  11. int []years;
  12. int yearMin;
  13. int yearMax;
  14. int yearInterval;
  15. float dataMin;
  16. float dataMax;

  17. void setup(){
  18. plotFont = createFont(“SansSerif”,20);
  19. textFont(plotFont);
  20. //load csv file
  21. data = new FloatTable(“ppl1920-1990-grs-t.csv”);
  22. years = int(data.getRowNames());
  23. yearMin = years[0];
  24. yearMax = years[years.length -1];
  25. yearInterval = 10;
  26. dataMin = data.getColumnMin(0);
  27. dataMax = data.getColumnMax(0);
  28. println(ceil(dataMax/volumnInterval));
  29. dataCeil = ceil(dataMax/volumnInterval) * volumnInterval;
  30. size(600,400);
  31. smooth();
  32. plotX1 = 160;
  33. plotY1 = 80;
  34. plotX2 = width - plotX1/2;
  35. plotY2 = height - plotY1;
  36. labelX = plotX1 -110;
  37. labelY = plotY2 +40;

  38. dataAreaWidth = plotX2 - plotX1;
  39. dataAreaHeight = plotY2- plotY1;
  40. }
  41. void draw(){
  42. background(022); // (1)background color
  43. fill(044);
  44. rectMode(CORNERS);
  45. noStroke();
  46. rect(plotX1,plotY1,plotX2,plotY2);
  47. strokeWeight(0.4);
  48. stroke(254);
  49. drawDataArea();
  50. stroke(112);
  51. strokeWeight(0.1);
  52. drawLabels();
  53. }

  54. void drawLabels(){
  55. drawTitleLabel();
  56. drawAxisLabels();
  57. drawYearLabels();
  58. drawYearGrid();
  59. drawVolumnLabels();
  60. }
  61. void drawTitleLabel( ) {
  62. fill(112);
  63. textSize(15);
  64. textAlign(CENTER,CENTER);
  65. text(“Population growth in Japan\n 1920 to 2000″,(plotX1+plotX2)/2,plotY1 - 40);
  66. }
  67. void drawAxisLabels( ) {
  68. fill(112);
  69. textSize(13);
  70. textLeading(15);
  71. textAlign(CENTER, CENTER);
  72. text(“Total \npopulation\n(Thousand)”, labelX, (plotY1+plotY2)/2);
  73. textAlign(CENTER);
  74. text(“Year”, (plotX1+plotX2)/2, labelY);
  75. }

  76. void drawYearLabels(){
  77. fill(112);
  78. textSize(12);
  79. textAlign(LEFT);
  80. int rowCount = data.getRowCount();
  81. for(int i=0;i < rowCount;i++){
  82. if(years[i] % yearInterval ==0){
  83. String yearText = data.getRowName(i);
  84. float x = map(int(yearText),yearMin,yearMax,plotX1,plotX2);
  85. text(yearText,x,plotY2+12);
  86. }
  87. }
  88. }

  89. void drawYearGrid(){
  90. int rowCount = data.getRowCount();
  91. for(int i=0;i < rowCount;i++){
  92. if(years[i] % yearInterval ==0){
  93. float x = float(data.getRowName(i));
  94. x = map(x,yearMin,yearMax,plotX1,plotX2);
  95. line(x,plotY2,x,plotY1);
  96. }
  97. }
  98. }

  99. void drawVolumnLabels(){
  100. fill(112);
  101. textSize(10);
  102. textAlign(RIGHT);
  103. float x = plotX1;
  104. float y;
  105. for(float v = floor(dataMin/volumnInterval)*volumnInterval;v <= dataCeil;v+= volumnInterval){
  106. y = map(v,floor(dataMin/volumnInterval)*volumnInterval,dataCeil,plotY2,plotY1);
  107. line(x-10,y,x,y);
  108. //println(v);
  109. text(floor(v),x-20,y+4);
  110. }
  111. }

  112. void drawDataArea(){
  113. beginShape();
  114. int rowCount = data.getRowCount();
  115. for(int i=0;i < rowCount;i++){
  116. float value = data.getFloat(i,0);
  117. float x = map(years[i],yearMin,yearMax,plotX1,plotX2);
  118. float y = map(value,floor(dataMin/volumnInterval)*volumnInterval,dataCeil,plotY2,plotY1);
  119. vertex(x,y);
  120. }
  121. endShape();
  122. }

  123. void keyPressed( ) {
  124. saveFrame(“japan_pl_##.png”);
  125. }

processing実行後に何かキーを押すと、連番で”japan_pl_01.png”という画像が保存されます。FloatTableというクラスは本のサンプルコードに含まれているものですが、http://benfry.com/writing/archives/3 からダウンロードできます。人口のCSVは統計局からダウンロードしたものをタブ区切りのcsvにしてます。

こんな感じで

  1. Year    Total
  2. 1920 55963
  3. 1921 56666
  4. 1922 57390
  5. 1923 58119
  6. 1924 58876
  7. 1925 59737
  8. 1926 60740.9
  9. 1927 61659.3
  10. 1928 62595.3
  11. 1929 63460.6
  12. 1930 64450
  13. 1931 65457
  14. 1932 66434
  15. 1933 67432
  16. 1934 68309
  17. 1935 69254
  18. 1936 70114
  19. 1937 70630
  20. 1938 71013
  21. 1939 71380
  22. 1940 71933
  23. 1941 71933
  24. 1942 71933
  25. 1943 71933
  26. 1944 73064
  27. 1945 71998
  28. 1946 73114
  29. 1947 78101
  30. 1948 80002
  31. 1949 81773
  32. 1950 83200
  33. 1951 84573
  34. 1952 85852
  35. 1953 87033
  36. 1954 88293
  37. 1955 89276
  38. 1956 90259
  39. 1957 91088
  40. 1958 92010
  41. 1959 92973
  42. 1960 93419
  43. 1961 94285
  44. 1962 95178
  45. 1963 96156
  46. 1964 97186
  47. 1965 98275
  48. 1966 99054
  49. 1967 100243
  50. 1968 101408
  51. 1969 102648
  52. 1970 103720
  53. 1971 105014
  54. 1972 107332
  55. 1973 108710
  56. 1974 110049
  57. 1975 111940
  58. 1976 110089
  59. 1977 114154
  60. 1978 115174
  61. 1979 116133
  62. 1980 117060
  63. 1981 117884
  64. 1982 118693
  65. 1983 119483
  66. 1984 120235
  67. 1985 121049
  68. 1986 121672
  69. 1987 122264
  70. 1988 122783
  71. 1989 123255
  72. 1990 123611
  73. 1991 124043
  74. 1992 124452
  75. 1993 124764
  76. 1994 125034
  77. 1995 125570
  78. 1996 125864
  79. 1997 126166
  80. 1998 126486
  81. 1999 126686
  82. 2000 126926

Processingを一言で説明しようとすると、Javaの描写機能を使用しやすいインタフェースで提供する言語環境(なのかな?)でしょうが、なんでProcessingに興味をもっていたかというと、これを使用した作品(っていうのがいいですね)に興味深いというか斬新なものが多かったからな訳です。

MusicBox: a truly powerful visualization of your music library:http://www.crunchgear.com/2008/12/15/musicbox-a-truly-powerful-visualization-of-your-music-library/
音楽のライブラリを可視化するソフト。ファイルのメタデータ(作者やジャンルなど)のみではなく、実際の音声データをスキャンしてマッピングする。

Aligning humans and mammals:http://benfry.com/infoseed/
人間とほ乳類の遺伝子配列をならべて描写した画像

Base26:http://toxi.co.uk/p5/base26/
英語の言葉同士の慣例性を表現した図。

仕事ではほとんどCRUDなWEBアプリケーションしか見ないのですが、こういうデータの重要性もさることながらどう見せるかでどれだけ印象や理解度が変わるかという事を考えるとおもしろい。色々遊んでみようと思います。

投稿者: t4ku

2月 3, 2009 3:44 am

Programming, Technology への投稿

タグ: