2016年2月3日水曜日

【作業メモ】

Androidで音を鳴らすのと、okhttpを使ってAPIを叩く奴を作った。


2016年2月1日月曜日

【作業メモ】2016.01.31

Herokuにsinatraで簡単なApiサーバーを作る。

/Gemfile
source "https://rubygems.org"
ruby "2.2.2"
gem 'sinatra', '1.4.7'
/Procfile
web: bundle exec ruby app.rb -p $PORT
/config.rb
web: bundle exec rackup config.ru -p $PORT
/app.rb
require 'rubygems'
require 'sinatra'
require 'json'

get "/app" do
  json_data = open("settings/shuzo.json") do |io|
    JSON.load(io)
  end
  json_data["items"].each do | item |
      content_type :json
      if params["id"] == item["id"]
        body << item.to_json
      end
  end
  body
end
/settings/shuzo.json
{
  "items":[{
    "id":"1",
    "name":"Kuwako",
    "age":"29"
  },{
    "id":"2",
    "name":"Matsuoka",
    "age":"48"
  }]
}
この辺が参考:https://devcenter.heroku.com/articles/getting-started-with-ruby-o

2015年11月6日金曜日

【OpenCV】ガンマとシグモイド

ディスプレイはRGBをそのまま表示できるわけではないらしい。とうわけで、表示する時にはディスプレイによって画像の補正がかけられているんだそうです。それがガンマ補正。詳しくはこちらがわかりやすかった。

画面にそのまま表示すると暗くなってしまうから、明るく補正をかけているんだけど、厄介なことにディスプレイやOSによってこのガンマの値が違うらしい。

このガンマ補正どこかで聞いたことあるなーって思ったら、photoshopの明るさ補正でも利用できるらしいとのこと(ここまでさっきのサイトでほぼ得た知識です。)

そういえばこれって、photohopのトーンカーブでいじった時の曲線と一緒なんですね。



void cv_CreateGammaTable(double gamma, uchar *lut){

      //ガンマ補正テーブルの作成
      int i;
      for (i = 0; i < 256; i++){
          lut[i] = (int)(pow((double)i / 255.0, 1.0 / gamma) * 255.0);
      }
}

で、結果が



だいたいこんな感じ、せっかくなのでトーンカーブをこんな感じにした時は、



シグモイド曲線と言って、コントラスト調整をかける時に利用する式を利用する。

void cv_CreateSigmoidTable(double sigmoid, uchar *lut){
      //コントラスト調整用のテーブルの作成
      int i;
      for (i = 0; i < 256; i++){
          lut[i] = 255.0 / (1+exp(-sigmoid*(i-128)/255));
      }
}

で、結果が

だいたいこんな感じで、photoshopでかけていた曲線をOpenCVで実現できる、もとい数式で表現できるという感じですね。photoshopの方を若干似せたつもりだったけど、似ていないけど、雰囲気は伝わるとは思うのでご愛嬌。

参考
ガンマ補正
ゴリラになる知識 - コントラスト調整
OpenCVでガンマ補正

追記:
ソースはこちらに上げていきます
https://github.com/tsukajizo/study_computer_vision

2015年5月1日金曜日

DroidKaigiへ参加した & ツールつくった話

少し時間があいてしまったけれど、先週の土曜日に、DroidKaigiへ参加してきました。
いつもは勉強会いって刺激ウケてもウケっぱなしなので、今回は何かつくろうって思って android-color-swatch-maker というのをつくりました。

DroidKaigiに参加した




今回の目当ては「デザイン関連の話」「ランタイムやメモリの話」でしたが、それ以外の話もとてもおもしろかったです。ただ、具体的な部分は一週間経つとうろ覚えですね。。。ブログはすぐ書くべし。とりあえず、聴いた発表はこちら。

  • マッチョなActivityにさよなら(基調講演)
  • アプリの企画、プロトタイプからリリースに至るまで
  • 進化するART
  • ARTのメモリ管理
  • 使えるGradleプロジェクトの作り方
  • デザイナーがXMLを書くことでできる改善しやすいアプリ開発
  • JellyBeanとKitKatで実現するマテリアルデザイン
  • Material Designを取り入れたデザインリニューアル

一部難しくてついていけない所はあったけど、発表はどれも面白くてとても勉強になりました。
普段はあまり触れない難しい話も、日々感じてたりしているような話も、聴いただけで終ったらもったいないな、と感じる発表が多くてとてもよかったです。

デザイナーとエンジニアの話


もともとMaterial Design関連の話に興味があったこともあって、デザイナーの方の発表に関してピックアップしてメモしておこうと思います。
デザイナーは二人発表されていて、どちらの方もエンジニアへの歩み寄りが凄いなって思いました。

「デザイナーがXMLを書くことでできる改善しやすいアプリ開発」中の
指定したカンプと違う・・・
実装してもらったら違和感があった・・・
ユーザー名長い人のこと考えてなかった・・・
画像あるときと無いときとあるんだった・・・
というのが以前コーディングをしていた時や、Flashをつくっている時にもよく感じと似ていて、結構悩みどころだったりしたので印象に残りました。

どちらのデザイナーの方もレイアウトのXMLを書いたり、Materialデザインを読んだりと、デザイナーがエンジニアリングに積極的に関与していくことで、問題の解決を図っているという印象でした。

自分はプログラマーなので、どうやってエンジニアリングをして主体的にデザインに関与していくかという所が課題で、発表聴いて気持ちがさめないうちにとにかくなにかをやってみようと思いました。 

ツールをつくる


エンジニアからデザイナーへの歩み寄りのアプローチとして、とりあえず思いつくのが、
  • デザインの調整しやすいシステムを作る
  • デザインのフローをエンジニアリングでスムーズにする
  • エンジニアとして共有できることを増やす
というところで、とりあえずその中でできることをしてみようと思ってツールをつくってみました。

つくったもの


Github - android-color-swatch-maker

特定のAndroidプロジェクトの中で設定されている色の情報を集めて、Illustrator、Photoshopで読み込んで利用することが出来るスウォッチライブラリ(Adobe Swatch Exchange )を作成することが出来るツールです。

使い方


実行
$ bundle install
$ ruby acsm.rb  --path 'Users/**/HogeProject/app/src/main/res/'  #プロジェクトのパス

結果
android.ase (サンプル用swatchファイル)


今の所、下のようにリソースファイルに設定されている色の情報しか取得できないので、そのうちLayoutのソースからも集めてきたり、逆にaseファイルからXMLを書き出せるような感じで便利にできたらと思ってます。
<resources>
    <item name="hoge" type="color">#FF33B5E5</item>
</resources>

最後に


DroidKaigiとてもいいベントでした、懇親会も含めて有意義な時間が過ごせました。発表者の皆様、スタッフの皆様お疲れさまです。ありがとうございました。
Written with StackEdit.

Written With StackEdit

Written With StackEdit

This is test for publishing notes written by markdown. with StackEdit.

public void publish(String text){
    mBlog.publish(text);
}

Written with StackEdit.

2014年2月13日木曜日

【SuperCollider】文法を学ぶ


さてさて、ちょっと音を出してみて「楽しい!」ってなっている訳だけど、ミュージシャンじゃないしいきなり音楽はつくれない、しかも正弦波しか今の所わからない。まぁ、これでもプログラマの端くれではあるので、この正弦波をならすプログラムをちょこっと改造しつつSuperColliderの文法について勉強してみることにした。

結論から火口。いや、書こう。
{
 var x = SinOsc.ar(1000,0.5);
 var y = SinOsc.ar(800,0.3);
 var z = SinOsc.ar(600,0.3);
Out.ar(0,Pan2.ar(x + y + z,0))
}.play
これが
{
 var sineChord = {
  arg col;
  do(col,{arg i;
    Out.ar(0,Pan2.ar(SinOsc.ar(i,0.5)))
    }
  )
 };
 sineChord.value([1000,800,600]).postln
}.play
こんな風になる。この二つは同じ音が出る。SuperColliderのページのLanguage - sclang には
- Single inheritance object-oriented and functional language.
- Similar to Smalltalk or Ruby with syntax similar to C or Javascript
と書いてある。オブジェクト指向と関数型言語ですよ。CかJavaScriptに似た文法をもったSmalltakもしくはRubyに似た言語だよって書いてある(っぽい。)
関数の書き方が
var  square = {arg x; x * x};  // ※1
square.value(8).postln;    // ※2
とそんな感じになる。
※1で関数を作成して、変数に代入。
※2で実行。

※1はJavaScriptっぽいし、上の例でdo(/*配列 */, /*関数*/)みたいなのはなんとなくrubyっぽい気がするぞ!

というわけで、上の二つは同じ音が出る訳ですが、普通のプログラミングとちょっと違うぞって言う面白さがある。音として出力されるのでたとえいくつかの音に分解して逐次実行しても最終的に出てくる音は現実空間で混じり合って同じになったりする。逆に逐次実行するということで時間的な意味合いも出てくる。

そういう意味でプログラミングの意味でも興味深いSuperColliderなのでした。

2014年2月10日月曜日

【Super Collider】ことはじめ


メディア芸術祭に行ってきて、なんか俺もやりたいというありがちで間の抜けた理由から、久々にSuperColliderを立ち上げてみた。

 久々にといっても、以前インストールして一度しか使ったことがなく、音が出るというのとvirturalboxとロゴが似ている(docに並べている)位の知識しかない。
使わないのに似ているというだけで並べられたアイコン
いろいろ試してみようと思ってまずはI googled it!

で、ここら辺とかを見ながらいろいろとやってみる。
{
var x = SinOsc.ar(1000,0.5);
var y = SinOsc.ar(800,0.3);
var z = SinOsc.ar(600,0.3);
Out.ar(0,x) + Out.ar(1,y) + Out.ar(0,Pan2.ar(z,0))
}.play

と簡単に正弦波をならしてみた。
OscというのはOscillatorのことらしい。これは多分シンセサイザーとかやっている人には当然の知識なんだろうなーとか思う。

 プログラミングの面白さもあるので、いろいろ想像するの楽しいなって思いながら、とりあえず今日はこの程度のしかやっていないのでもうすこし触ってみようかなとも思う。

2013年12月19日木曜日

初めて買ったRubyの書籍がパーフェクトRubyな話。

パーフェクトRubyアドベントカレンダーの19日目です。

正直にお話しします。まだ、あまり読んでいません。


すいません、すいません。
パラパラめくったりはしていますが、他の本を読んでいる微妙なタイミングで買ってしまったのと、今の所Rubyのリファレンスマニュアルを見たりとか、rubyで書かれたコードとかを読みながら、小さなプログラムを組んでいる程度なのでちゃんと読めていないです。手元にあるのにもかかわらず、どこから読んでいいのかわからないという、頓珍漢な答えをしてしまうくらいです。
どこから読もうと思っているのかは、ちゃんとあるので最後の方に書くつもりです。

今、普段書いているのはActionScript3.0 ですが、作業用の補助ツールとかに好んで書いているのはRubyだったりします。

他にもいろいろな書籍があるのに、

「正直にお話しして、まだあまり読んでいないのに何故パーフェクトRubyを最初に選んだか」


という話をします。理由は3つあります。3っつ合わさってこその決め手です。


1. Rubyだから


 もともとフロントエンドで仕事をしていて、ActionScript3.0やJavaScriptを書いていたのですが、どちらもツールとして使うのには扱いづらく、いろいろと他の言語を試してみたりしてました。最初はPHP、次に触ったのはPythonでした。そして、その次に触ってみたのがRubyでした。(※1)
 なんとなく今はRubyがしっくりきている気がしているので、Rubyを使っています。

2. パーフェクトシリーズだから


 PHPを勉強していた時にパーフェクトPHPを買いました。Androidの仕事をした時にパーフェクトJavaを買いました。PHPはあまり使う機会はなかったですが、パーフェクトPHPはフレームワークを作る所の章が今でも参考になっていて、パーフェクトJavaは実際に書く機会があったこともあってとても参考になりました。( ※2 )

3. 読んでみたいと思ったから


 実はプログラマとして最初に触れた自分以外の書いたコードが著者の一人の@sugamasaoさんの書いたコードでした。また最初に一緒にコードを書いたのも@sugamasaoさんでした。学生時代に少しコードを書いていたとはいえ、一人でずっと書いていたこともあって、もう4年前ですが、今でもどういった処理で、どういう目的で書かれていたということをなんとなく思い出せるくらい、とても学んだことがたくさんありました。(自分の書いたコードはすぐ忘れるのに! )

 そういったこともあって、仕事とはあまり関係ないコードで最初にレビューを個人的にお願いしてみたのも@sugamasaoさんだったりします。

 そんな方が共著で一部を書いているRubyの本である。。。。。。あとはわかりますね?


まとめ


 そんなこんなで、買わないわけにはいかない!とおもって、勢いで買ったパーフェクトRubyですが、実はまだちゃんと読めていません。買った理由が完全に個人の経験に依存した理由で、他の方の参考になる気がしません。他の方が参考になる所を書いてくださっているので、自分もそれを参考にしつつ読んでいくつもりです。

 とここまで書きましたが、自分が読もうとしている所は決まっていて、今ちょっとずつサーバーサイドのことを学びつつ、ブラウザで使えるツールなんかをWebrickをつかって書いていたりしていて、ちょっといろいろと学びたいことができてきたので、とりあえず週末あたりにTODOツールを作る所からでも手をつけてみようかなと思っています。

Rubyちゃんと使えるようになりたいぞ!

※1 他の言語をdisれるほどつかってないので、ちゃんとした理由はありません。
※2 よく言えば信頼。わるく言えば妄信。

2013年12月13日金曜日

【CoffeeScript】for文の戻り値メモ

「CoffeeScriptの関数は明示的にreturnするべき」って言う記事が流れてきて、CoffeeScriptは触った事なかったけどちょっと気になった事があったのでメモ。

「returnを明示的にしないと元の記事だと無駄なコードが出力される」

 って、さっきの記事にはあったんだけど、Rubyとかもreturnを明示しなくても戻り値のある言語だし、わざわざreturnを明示しなくても戻り値がちゃんとあるというのにはちゃんと意味があると思ってて、できればreturnを明示しなくてもちゃんと期待通りの処理が行われる実装や設計にしていくのが好ましいようなきがした。それを意識して書いてあれば、きっと無駄なコードが出力される事もなさそうな気がする。

そこでRubyのコードとちょっと比較してみた。

 まずはCoffeeScriptのコード
(console.logの戻り値がundefinedみたいなようなのでRubyと同じような結果になるようにputsを定義しています)
puts = (v)->
     console.log(v)
     return v
 
sample = ->
  for i in [0,3,5]
    puts(i + 1)
                                                                                                                                                      
result = sample()
console.log(result)
結果はこうなる。
1
4
6
[ 1, 4, 6 ]
次はRubyのコード
def test
    for num in [0,3,5] do
       puts num + 1
    end
end 

result = test
print result
結果はこうなる。
1
4
6
[0, 3, 5]
この二つを比べてみると、CoffeeScriptとRubyの戻り値の評価の方法が違う事がわかった。

Rubyのリファレンスを見てみると、「 for文はローカル変数のスコープに影響を及ぼさない点が 異なるからです。」ってことなので配列の定義をしている所が最後の評価として返ってきているんだと思う。

CoffeeScriptの方は、for文の中で処理された値を配列にいれて返している。何でそうなっているのかはわからないけれど、そういう評価の方法だとわかっていれば、for文でに保存してそれを配列として返すというjsの出力は無駄というわけではない。

さて、元記事にあるように return文を仕込んだ処理が以下のように書いてあったとする。
puts = (v)->
     console.log(v)
     return v

sample = ->
  for i in [0,3,5]
    puts(i + 1)
  return

result = sample()
console.log(result)
そうすると以下のように処理が行われる。
1
4
6
undefined
何かが必ず「返り値」になるっていうのは、何がどのような順番で評価されるかって言う事を意識して実装しないとってことで、それは結構プログラムを書く時に意識していた方がいい事だと思うし、戻り値が違うのはテストを書いていたりするとおかしくないのでむやみやたらにreturnで返すよりも、できるだけreturnを返さないように常に戻り値をいしきしてじっそうするほうがいいきがした。

同じような出力を期待するには下のような感じでもできるけど、結局returnは使ってない。return使わなくてもよけいなものを出力しないってことは多分できて、結局作業をする人の慣れとか、その時どんなプロジェクト上の最適化をしなくちゃいけないかって所で、バランスをとっていく所なんだと思う。なので元記事の「必ずreturn」を書くって言うのも一つの方法なんだろうと思う。

ただ、元々のJavaScriptがイケてないからこそ、「JavaScriptに変換する言語を作ろう」みたいになったはずで、そのために使っているはずなのに、出力されるJavaScriptをみてCoffeeScriptの処理の最適化の方法を考えていくのも何となく悔しい気がするのでした。
puts = (v)->
  console.log(v)
  return v

sample = (list,x=0)->
      puts(list[x])
      sample(list,x+1) if list.length > x + 1

result = sample([0,3,5])
puts result
書き出されたコード
// Generated by CoffeeScript 1.6.3                                                                                                                    
(function() {
  var puts, result, sample;

  puts = function(v) {
    console.log(v);
    return v;
  };

  sample = function(x) {
    var list;
    if (x == null) {
      x = 0;
    }
    list = [0, 3, 5];
    puts(list[x] + 1);
    if (list.length > x + 1) {
      return sample(x + 1);
    }
  }; 
                                                                                                                                                      
  result = sample();
                                                                                                                                                      
  puts(res);
                                                                                                                                                      
}).call(this);

2013年12月4日水曜日

Androidの勉強をしよう。

Androidに興味があると言っておきながら、全然目に見える形でアウトプットが出せていないので、Androidの勉強をしたいと思います。というわけで現状を整理。

今、ActionScript3.0を書いていて、それだけだとこの先どうにもならないとおもっているので、ちゃんとアウトプットもしてきたいですね、という所でAndroid勉強しようとか思ってる。あ、でも一応JavaScriptとかを仕事で書いていたときもありました。

Androidに関して言えば、触るのが初めてという訳ではなくてちょっとだけ仕事で実装した程度、Androidの実装されたコードはたまに読んでいるという程度。ただ、細かいデバイス依存の実装や、バージョン互換性の問題等はわかっていないでよくしらないよ、といったところです。

最初にAndroidを触ったときは、助っ人みたいな形だったので(Java書いた事ないのに!)、早急にコードを扱わなくてはいけなくて、

http://dsas.blog.klab.org/archives/52003951.html
http://blog.kmckk.com/archives/3551546.html
http://itpro.nikkeibp.co.jp/article/COLUMN/20091126/341182/

ここら辺とActivityThread.javaとかActivityManager.javaとかのソースを読みつつ、ActivityやIntentのライフサイクルとかを把握してプロダクトコードと格闘してた。
 まぁ、そんなこんなで興味をもつにはもったのだけど、たまにSDKのコードをあさって読んだりしている程度。

さて、いろいろ見てきた所Binderの仕組みを理解するといろいろと理解が深まりそうなのでそこを勉強してきたいです。とりあえずこの辺から見ていきたいと思います。

http://togetter.com/li/110186
https://www.nds.rub.de/media/attachments/files/2011/10/main.pdf


2013年8月28日水曜日

Markdownでドキュメントを書きたい。


Markdownでドキュメントを書きたい。

自分用のメモとかドキュメントとかつくるのにSphinxを使っていたんだけど、どうもなかなかreStructuredTextにこなれないし、自分用にガッツリ勉強する気にもなれない。そのうちGithubのGistを使うようになってきて、Markdown使いたいなって思うようになった。というかGistに張ったものをそのまま使ったり、書いたものをそのままGistに張ったりしたい。

というわけで、Markdownをhtmlに変換できるようなのを探して"markdown html 変換"で検索した所、pandocというのが出てきた。このpandoc、MarkdownをreStructuredTextに変換できるとも書いてあって、じゃあこれを使おうって思った。

とりあえずインストール。Haskellでつくられたツールだそうで、Haskellのパッケージマネージャで入れられるそうだ。
参考 http://qiita.com/sky_y/items/80bcd0f353ef5b8980ee
(※pandoc単体のインストーラもあるっぽい)

といってもHaskellの環境がないので、まずはHaskellの環境をインストールした。

$brew install haskell-platform
続いてpandocをインストール。たしかこれで動いたはず。
$ cabal update
$ cabal install pandoc

インストールできたので、適当に書いて出力してみた。
sample.mdというファイルで作成してsample.htmlというファイルに出力。
# Sample

## Gohan
1. Onigiri
2. Katsudon
3. Karaage

```
$echo "Onigiri Mogu Mogu"
```
---

```
$echo "Mecha Mecha Oishi!"
```

ついで出力。
$ pandoc sample.md -s -o sample.html


おおっ、ちゃんと出力されてるすげー!。すげーけど味気ない。
味気ないのでCSS当てる事にした。面倒くさいのでGist風のCSSを探してきて拝借。 https://gist.github.com/andyferra/2554919

自分でタグ書くの面倒だからRubyで挿入できるようにした。書いてて、なんだかすごい回りくどい事しているような気がしたけど気にしない。Rubyの勉強したと思う事にした。

#!/usr/bin/env/ruby
##https://gist.github.com/andyferra/2554919
if __FILE__ == $0
  usage=  """
usage
-------------------
giss [filename]"""
 
  css = """ """
  curdir = Dir::pwd
  appdir = File.dirname($0)
  if ARGV.length == 0
    print usage
    exit
  end
 
  filename = ARGV[0]
  file = File.open(filename) do |f|
    f.read
  end
  if file.index("gist.css").nil?
    n_head = file.index("")
    file.insert((n_head + 6),("\n" + css))
    open(filename, "w") do
      |f| f.write file
    end
  end
  unless File.exist?("gist.css")
    puts `cp #{appdir}/gist.css #{curdir}/gist.css`
  end
end

そうして出てきたのがこちら。


満足。pandocとても良いですね。もっと他の方法もありそうな気がするけどとりあえずこれで。

2013年6月21日金曜日

【JavaScript】Canvasを使ってとりあえず3Dの球を書いてみようと思ったんだけど、いまいちなんだかよくわからない。


ガッと書きたくなって、ざっと書いたので雑だ。
var Tk = Tk || {};

Tk.gui = {};
Tk.canvas = {};
Tk.t3d = {};

//テキトーなのでなんとかしたい 
Tk.t3d.objct= null;


Tk.gui.getElem = function(id){
    return document.getElementById(id)
}



Tk.canvas.getCanvasContext = function(id){
    var canvas = Tk.gui.getElem(id);
    if (canvas.getContext) {
 var context = canvas.getContext('2d');
    }
    return context
}


Tk.canvas.animate = function(ctx,time){
    setInterval(
 function(){
     Tk.canvas.update(ctx)
 }
 ,time)
}

Tk.canvas.clear = function(ctx){
    ctx.fillStyle = "#FFFFFF"
    ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);
}

Tk.canvas.setup = function(ctx){
    var sp= new Tk.t3d.Sphere(200,10,10);
    
    Tk.t3d.drawMesh(ctx,sp.points,sp.indices);
    Tk.t3d.object = sp;
}

//更新しているけど、別に動いていない。
Tk.canvas.update = function(ctx){
    Tk.canvas.clear(ctx);
    var sp = Tk.t3d.object;
    Tk.t3d.drawMesh(ctx,sp.points,sp.indices);
}

Tk.t3d.Point3d = function(x,y,z){
    this.x = x;
    this.y = y;
    this.z = z;
}

Tk.t3d.Point = function(x, y){
    this.x = x;
    this.y = y;
}

Tk.t3d.Sphere = function(r,rows,cols){
    this.r = r;
    this.rows = rows;
    this.cols = cols;
    this.points = setPoints(r,rows,cols);
    this.indices = setIndices(r,rows,cols);
    
    function setPoints(r,rows,cols){
 var pList = [];
 for(var i = 0;i < rows; i++){
     for(var j = 0;j < cols; j++){
  var angle1 = Math.PI * 2 / ( cols -1 ) * j
  var angle2 = Math.PI * i / ( rows -1 ) -Math.PI/ 2;
  var point = new Tk.t3d.Point3d(
      r * Math.cos(angle1) * Math.cos(angle2),
      r * Math.sin(angle1) * Math.cos(angle2),
      r * Math.sin(angle2)
  );
  pList.push(point)
     }
 }
 return pList;
    }


    function setIndices(r,rows,cols){
 var indices = [];
 for(var i = 0;i < rows;i++){
     for(var j = 0;j <cols; j++){
  if( i < rows - 1 && j < cols -1){
  indices.push([
      i * cols + j,
      i * cols + j + 1,
      (i + 1) * cols + j])
  indices.push([i * cols + j + 1,
        (i + 1) * cols + j + 1,
        (i + 1 ) * cols +j]);
  }
     }
 }
 return indices;
    }
}

Tk.t3d.toPersePectionPoints = function(points){
    var parsePection = 200;
    var forcalLength = 250;
    var pList = [];
    for(var i = 0; i < points.length;i++){
 var scale = forcalLength / ( forcalLength + points[i].z + parsePection)
 pList.push(new Tk.t3d.Point(points[i].x * scale, points[i].y * scale));
    }
    return pList;
}

Tk.t3d.draw3d = function(ctx,points){
    var drawPoints =Tk.t3d.toPersePectionPoints(points)
    for(var i = 0; i < drawPoints.length;i++){
 ctx.beginPath();
 ctx.arc(drawPoints[i].x + 100, drawPoints[i].y + 100, 1, 0, Math.PI*2, false)
 ctx.fill();
    }
    
}

Tk.t3d.drawMesh = function(ctx,points,indices){
    var drawPoints =Tk.t3d.toPersePectionPoints(points)
    var offsetX = ctx.canvas.width / 2;
    var offsetY= ctx.canvas.height / 2;
    for(var i = 0; i < indices.length;i++){
 var index = indices[i]
 ctx.beginPath();
 ctx.moveTo(points[index[0]].x + offsetX  ,points[index[0]].y + offsetY );
 ctx.lineTo(points[index[1]].x + offsetX  ,points[index[1]].y + offsetY);
 ctx.lineTo(points[index[2]].x + offsetX  ,points[index[2]].y + offsetY );
 ctx.lineTo(points[index[0]].x + offsetX  ,points[index[0]].y + offsetY);
 ctx.stroke();
    }
    
}

Tk.t3d.main = function(){
    var ctx = Tk.canvas.getCanvasContext("canvas_20130621");
    Tk.canvas.setup(ctx);
    Tk.canvas.animate(ctx,200);
}

Tk.t3d.main();

2013年3月12日火曜日

【Ruby】WebrickのProxyContentHandlerとProcクラス



前々回の記事webrickでプロキシサーバをつくろうとしてデータを書き換えたりするために使っていた際、ハンドラのProxyContentHandlerにProcクラスを使っていたけれど これをどうにかして、別のクラスにして置き換えたいと思った。
  handler = Proc.new(){|req,res|

    if "#{req.host}#{req.path}" == REPALCE_TARGET
      res.body = REPLACE_CONTENT
    end
  }
Procについて調べてみて出てきた説明がこちら
ブロックをコンテキスト(ローカル変数のスコープやスタックフ レーム)とともにオブジェクト化した手続きオブジェクトです。
うむ、いまいちどうしたらいいのかわからなかったのでいろいろと試行錯誤しようとしたけれど、なかなかうまくいかなかった。そこで、とりあえず適当にクラスをつくって突っ込んでみる事にした。
class Handler  
  def initialize()
  end
end
これを
handler= Handler.new
として、プロキシを設定し、適当なページにアクセスすると以下の表示が帰ってきた。
Internal Server Error

undefined method `call' for #
WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20) at doc.ruby-lang.org:80
methodのcallが無いという事なので、Procの時に実装していた引数をもたせたcallというメソッドを実装
class Handler
  
  def initialize()
  end
  
  def call(req,res)
  end
  
end
すると、ページがきちんと表示された。よし、これにて一件落着。 といいたい所だけれども、とりあえずwebrickのhttpproxy.rbとproc.cを見てみた所、何となく、これでも問題なさそうだ。

https://github.com/ruby/ruby/blob/trunk/proc.c https://github.com/ruby/ruby/blob/trunk/lib/webrick/httpproxy.rb

 動くっちゃ動くけど、この実装はruby的にいいのかどうか。

2013年2月25日月曜日

【Ruby】yamlをrubyで書き出そうとしたときのメモ


設定ファイルの書き出し、書き込みみたいな事がしたかったので調べてて
使った事無かったyamlを使ってみようと思った。なんか見やすいですしおすし。
Animal:
 gorira: Goritaro
 cat  : Nyanko
 horse : Umazo
こんな風にかける。 ファイルに書き出したかったので、調べてみると、
open("./test.yml","w") do |f|
 YAML.dump(hoge,f)
end
でファイルに書き出せるっぽい。しかもrubyで書いたオブジェクトをそのままの形で書き出す事ができると、どこかで見た気がしたので、下みたいに書いて出力してみた。
#!/usr/bin/ruby
require "yaml"

hoge = "test1"
fuga = "test2"

class Hoge
  attr_accessor :hoge,:fuga
  
  def initialize(hoge,fuga)
    @hoge = hoge
    @fuga = fuga
  end
end

class Piyo
  attr_accessor :piyo

  def initialize(piyo)
    @piyo = piyo
  end
end

piyo = Piyo.new(fuga)
hoge = Hoge.new(hoge,piyog)
sample = hoge.to_yaml

open("./test.yml","w") do |f|
  YAML.dump(hoge,f)
end
すると、こんな風に書き出された。
--- !ruby/object:Hoge
hoge: test1
fuga: !ruby/object:Piyo
  piyo: test2

違う!わたしが欲しいのはこんなYAMLちゃんじゃないわ!!!1
なんか’!ruby’とか入ってるのは、rubyのオブジェクトだからっぽい。
hoge = {'Hoge' =>{'hoge'=>'test1','Piyo'=>{'piyo'=>'fuga'}}}
これだと普通に出力されました。
---
Hoge:
  hoge: test1
  fuga:
    piyo: test2
これだよ!ほしかったのは

そこで、調べてみるとオブジェクトの’taguri’と'to_yaml_style'というのを書き換えてあげるといいといいらしい。いいらしいがうまくいかず(前確かめたときはちゃんとできたのに)。
(gihyo 言語別 YAML用ライブラリ徹底解説)

いろいろと検索結果をぶらぶらとしていて、たどりついたココ(YAML/オブジェクトシリアライズ処理を読む)に習って、rubyのソースを'to_yaml'で検索してみるとそれっぽいのが出てきました。
ちなみに確認したバージョンはruby-1.9.3-p392
#ext/syck/lib/syck/rubytype.rb
class Object
    yaml_as "tag:ruby.yaml.org,2002:object"
    def to_yaml_style; end
    undef to_yaml_properties rescue nil
    def to_yaml_properties; instance_variables.sort; end
 def to_yaml( opts = {} )
  YAML::quick_emit( self, opts ) do |out|
            out.map( taguri, to_yaml_style ) do |map|
    to_yaml_properties.each do |m|
                    map.add( m[1..-1], instance_variable_get( m ) )
                end
            end
        end
 end
    alias :syck_to_yaml :to_yaml
end

これだけ見てもさっぱりわからないですね。と、ここまでやって思ったんだけど、よくよく考えると今やりたいことはyamlでやる必要ないかなぁと。(←今ココ

rubyでyamlを書き出そうとして、なんとなしにrubyのライブラリのソースにたどり着いたので、いろいろと中身も見ていければなぁと思ったりしましたメモでした。(まわりくどい)

 ※文体変えた

2013年2月22日金曜日

【Ruby】WEBrick でプロキシサーバをつくってみる


Macのブラウザでネットワーク関連の処理をあれこれしたいと思った時に、Windowsを利用していた時に使っていたFiddler的なものが欲しくなりました。WEBrickを使ってプロキシサーバをつくれば、似たような事ができる(?)と教えていただいたので、早速試してみる事にしました。 

サーバサイドのスクリプトも、Ruby自体もあまり触った事がなかったので、ついでにどんな風にかけるのかあれこれいじりながらやってみる事にしています。いろいろとやってみたい事があるのですが、とりあえず置き換えの方法だけでもメモしておきます。

 Webrickを利用している部分は抜き出してクラスに。まだまだいろいろと機能があるようなのでいじりながら何ができるかを検討中。
##./lib/proxy.rb
#!usr/bin/ruby
require 'webrick'
require 'webrick/httpproxy'
include WEBrick

class Proxy
   attr_accessor :config

  def start
    print @config
    @server = WEBrick::HTTPProxyServer.new( @config )
    Signal.trap('INT') do
     @server.shutdown
    end
    @server.start
  end

  def shutdown
    @server.shutdown
  end
   
end
設定ファイル(yml)
server:
 :BindAddress    : '127.0.0.1'
 :Port           : 10080
 :DocumentRoot   : ''
 :CGIInterpreter : '/usr/bin/ruby'

handlerの中身の部分は、あまりいろいろ試してみていないのでこれからいろいろと試しつつ、できそうな事があれば実装していこうと思います。URLを比較する部分とかはまだ適当です。
##./main.rb
#!usr/bin/ruby
require './lib/proxy.rb'
require 'yaml'

@server = Proxy.new

REPLACE_CONTENT =<<EOF
<body>
<h1>Oh!</h1>
<body>
EOF


REPALCE_TARGET = "tsukajizo.com/"

def start_proxy
  #Handler
  handler = Proc.new(){|req,res|

    if "#{req.host}#{req.path}" == REPALCE_TARGET
      res.body = REPLACE_CONTENT
    end
  } 
  
  #プロキシサーバの設定
  config = YAML.load_file('./config.yml')
  server_config = config['server']
  server_config[:ProxyContentHandler] = handler
  
  #プロキシサーバの起動
  @server.config = server_config
  @server.start
end

start_proxy
なんか、こうもうちょっと使いやすい感じにしていきたいですね。

とりあえず。
 →

こんな感じです。

2012年5月13日日曜日

【Qt】Macで、QMenuを使おうとしたときの覚え書き。


Qtの入門書(※1)のサンプルをいじっているのですが、作成するアプリケーションが一つのメソッドの動作を確かめるためには割と大きくて、各処理がちゃんとどう実行できるか確かめるために小さなアプリケーションを作成したところ、若干つまずいた部分があったので、メモ。

とりあえず、windowを出して、終了だけできるアプリケーションを実装してみた。そこで、下記のコードのように、ファイルメニュー、ヘルプメニューを作成してみた所、予想としていた結果と違う結果が出てしまった。

void MainWindow::createMenus()
{
  fileMenu = menuBar()->addMenu(tr("&File"));
  fileMenu->addAction(showTestAction);
  fileMenu->addAction(exitAction)
  
  helpMenu = menuBar()->addMenu(tr("&Help"));
  helpMenu->addAction(aboutAction);
  helpMenu->addAction(aboutQtAction);
}

で結果がこれ。

ヘルプメニューは表示されないし、ファイルメニューに設定したはずのメニューはなんか「winTest」っていう特に設定していない(アプリケーション名の)メニューの方に追加されてしまっているし、利用する分には、問題なかったとしても、想像していたのと違う動きをしているのでちょっと調べてみた。

で、Qt本家の記事(http://doc.trolltech.com/4.5/mac-differences.html#menu-bar)によると結局、OSネイティブの使用に合わせてラッパーをつくっているので、上のでwinTestに出ているものに関しては、自動的にこちらのメニューに追加されてしまうみたい。

とはいえ、どういうタイミングでこのメニューに追加されてしまうのかというのがわからなかったので、いろいろといじってみた所。下のコードを

void MainWindow::createActions()
{
  //------------ 略 ----------------//
  
  aboutAction = new QAction("&About",this);
  aboutAction->setStatusTip("Show about this application.");
  connect(aboutAction,SIGNAL(triggered()),
   this,SLOT(aboutTest()));

  //------------ 略 ----------------//
}

このように書き換えてみると
void MainWindow::createActions()
{
  //------------ 略 ----------------//
  
  aboutAction = new QAction("&Bout",this);
  aboutAction->setStatusTip("Show about this application.");
  connect(aboutAction,SIGNAL(triggered()),
   this,SLOT(aboutTest()));

  //------------ 略 ----------------//
}
こんな感じの結果になった。
というわけで、原因はここにあるという事はわかった。実装上の仕組みはまだよくわかっていないので、設定方法の仕組みがわかったら、またメモろうとは思いますが。
とりあえず、Macのメニューの設定時にびっくりしないようにメモ。

※1「入門 Qt 4 プログラミング」
Jasmin Blanchette (著), Mark Summerfield (著), 杵渕 聡 (翻訳), 杉田 研治 (翻訳)
 - amazon

2012年5月7日月曜日

【AS3.0】アプリケーションフレームワークをつくってみた。



ActionScript3.0でアプリケーション用のフレームワークをつくってみた。
Github- Framingo
アプリケーション設計の勉強と、ActionScriptを触り始めてちょうど2年半くらいになるのでそのまとめという意味で、アプリケーションプロトタイピング用の、フレームワークをつくってみました。基本的には自分が使う用、もしくは学習したナレッジの蓄積用として継続的に開発していくつもりです。

世に言うMVCというのを意識してつくったつもりですが、いろいろ調べていくと割と曖昧で、結局なにがMVCなのかっていうのは未だに消化しきれていない感じです。
FlashだとViewの部分を扱う事が多いような気がしますが、処理系が複雑になっていくにつれて、どのように整理してコードを実装して良いのかが、わからなくなってしまう事があったりもしたので、できるだけ見た目が変化する処理の部分と、オンメモリで扱うアプリケーションのデータに対する操作を切り離せるようにしたつもりです。

実装上の主なコンセプトは

  1. ユーザーのアクションに対して、一対一の動作をアプリケーションが行うようにする。
  2. IDEと連携した作業もしやすいようにする。
  3. シンプルな処理の仕組みだけを提供し、なんでもできてしまうような便利メソッドはできるだけ提供しない。
  4. 素早い実装と、コード管理のしやすさを目指す。

こんな感じです。現在バージョンはver 0.1となっていますが、現在はようやく動作するという感じです。まだ実装しきれていない部分や、まったく実装のないクラスなどがいくつかあったりします。プロトタイピング用を目指しているので、さっと実装できるのが良いと思っているのですが、現状結構めんどうくさくて解りにくいです。
XMLで記述して、アプリケーションのひな形やシーン構成が作成できるようにしようと思っていますが、現在は以下のクラスの特定メソッドを必要に応じて継承しないと例外が出るつくりになっています。

src/framingo/core/FMCoreClass.as
src/framingo/model/manager/DataManager.as
src/framingo/model/process/AbstractProcess.as
src/framingo/model/process/ProcessFlow.as
src/framingo/view/factory/SceneFactory.as


また、テストコードやサンプルコード、ドキュメントに関しては、順次整理しようと思っています。まだまだ稚拙な実装は多いと思うので、順次ブラシュアップしていければと思っています。

以下クラス構成

.
`-- framingo
    |-- core
    |   |-- FMApplication.as
    |   |-- FMCoreClass.as
    |   |-- FMCoreSetting.as
    |   |-- config
    |   |   `-- FMVersion.as
    |   |-- error
    |   |   |-- ErrorManager.as
    |   |   `-- UnimplementedError.as
    |   |-- log
    |   |   `-- Logger.as
    |   `-- system
    |       `-- SystemManager.as
    |-- data
    |   |-- AbstractDataGroup.as
    |   |-- AbstractProcessData.as
    |   |-- SceneDataGroup.as
    |   `-- action
    |       |-- AbstractAction.as
    |       |-- ActionSync.as
    |       |-- FlowAction.as
    |       |-- IDataTransfer.as
    |       |-- RenderAction.as
    |       `-- SceneAction.as
    |-- model
    |   |-- events
    |   |   |-- FlowEvent.as
    |   |   |-- ProcessActionEvent.as
    |   |   `-- ProcessEvent.as
    |   |-- factory
    |   |   `-- FlowFactory.as
    |   |-- manager
    |   |   |-- DataManager.as
    |   |   `-- ModelManager.as
    |   `-- process
    |       |-- AbstractProcess.as
    |       `-- ProcessFlow.as
    |-- presenter
    |   |-- ActionPresenter.as
    |   |-- IActionReceivable.as
    |   `-- IThrowableAction.as
    `-- view
        |-- events
        |   |-- ActionObjectEvent.as
        |   |-- RenderObjectEvent.as
        |   |-- SceneEvent.as
        |   `-- SceneManagerEvent.as
        |-- factory
        |   `-- SceneFactory.as
        |-- interactive
        |   `-- ActionObject.as
        |-- manager
        |   |-- DialogManager.as
        |   |-- SceneManager.as
        |   `-- ViewManager.as
        |-- render
        |   |-- IRenderableData.as
        |   `-- RenderObject.as
        `-- scenes
            |-- AbstractScene.as
            `-- SceneChildren.as

2012年2月22日水曜日

【Python】ファイルを検索して行番号を取得する

Pythonを使ってみたかったので、とりあえず書いてみた。
現在のディレクトリ以下のファイルを検索して、指定の文字列のある行番号を取得する。
なんとなくだけど、いまいちよくわかってない部分があったり。



import os
import glob


def get_filepath(rootpath,term):
file_list = []
for root,dir,files in os.walk(rootpath):
for fname in glob.glob(os.path.join(root,term)):
file_list.append(fname)
return file_list


def load_files(file_list):
file_set = {}
for filepath in file_list:
fname = filepath[filepath.rfind("/")+1:len(filepath)]
f = open(filepath,"r")
file_set.update({fname:f})
return file_set

def close_files(file_set):
for f in file_set.values():
f.close()


def get_line_number_with_term(file_set,terms):
line_set = {}
for name,f in file_set.items():
line_number = []
count = 0
for line in f:
if(line.find(terms) != -1):
line_number.append(count)
count+=1
line_set.update({name:line_number})
return line_set

if __name__ == '__main__':
curdir = os.getcwd()
extention =( "*." + raw_input("[ Enter extention ]:") )
pathList = get_filepath(curdir,extention)
fileset = load_files(pathList)
terms = raw_input("[ Enter terms ]:")
lineSet = get_line_number_with_term(fileset,terms)
close_files(fileset)
print lineSet


実行結果

bash-3.2$ python hoge.py
python hoge.py
[ Enter extention ]:py
py
[ Enter terms ]:def
def
{'hoge.py': [5, 13, 21, 26]}

2011年12月21日水曜日

【php】XMLを読み込んで複数のコマンドを実行する

前回のプログラムを少し拡張してみた。XMLをロードして複数コマンドを実行する。


<?php
doMultiProcesses($argc , $argv);
//コマンド
function doMultiProcesses($num,$param){
if($num < 2){
echo "コマンドが入力されていません。\n";
return;
}
execProcess($param);
}

//コマンドの実行
function execProcess($arg)
{
switch($arg[1]){
case "xml":
if(count($arg) < 3){ echo "引数が足りていません\n";return;}
$process = new XMLLoader($arg[2]);
break;
default:
echo "設定されていないコマンドです。\n";
return;
}
$process->execute();
$processes = new Launcher();
$processes->setProcesses($process->processes);
//$processes->isQueue = false;
$processes->execute();

}


/***********************
*
* 抽象クラス
*
**********************/
abstract class AbstractProcess{
abstract public function execute();
abstract public static function toString();
}

class Process
{
public $params;
public $name;

public function Process($name,$params){
$this->name = $name;
$this->params = $params;
}

public static function create($name,$params)
{
$className = $name;
$classParams = $params;
if(class_exists($className)){
$process = new $className($classParams);
}else{
echo $className . "という処理がみつかりません。\n";
}
return $process;
}
}

/***********************
*
* 複数コマンドの実行用
*
***********************/

final class Launcher extends AbstractProcess{

public $processes;
public $isQueue;

public function Launcher(){
$this->isQueue = true;
}

public function setProcesses($value){
$this->processes = $value;
}

public function execute(){
while(count($this->processes) > 0){
if($this->isQueue){
$process = array_shift($this->processes);
}else{
$process = array_pop($this->processes);
}
$process->execute();
}
}

public static function toString(){
return "Launcher";
}
}


/***********************
*
* コマンドローダー
*
***********************/

class XMLLoader extends AbstractProcess{



private $path = "";
public $processes;

public function XMLLoader($path){
$this->path = $path;
$this->processes = array();
}

public function execute(){

if(!file_exists($this->path)) {
echo "ファイルが存在しません\n";
return;
}
try{
$xml = simplexml_load_file($this->path);
}catch(Exception $e ){
echo "XMLの書式が間違っています\n";
return;
}

foreach( $xml->process as $process){
$name = (string)($process->name);
$param = (string)($process->param);
$prc = Process::create($name,$param);

if($prc instanceof AbstractProcess)
array_push($this->processes,$prc);
}
}

public static function toString()
{
return "XMLLoader";
}
}

/***********************
*
* サンプルコマンド
*
***********************/
class Test extends AbstractProcess
{
private $param;
public function Test($param){
$this->param = $param;
}

public function execute(){

echo $this->param . "\n";
}

public static function toString()
{
return "Test";
}

}




これを使って以下のXMLを読み込んで実行する。

<data>
<process>
<name>Test</name>
<param >param1</param>
</command>
<process>
<name>Test</name>
<param >param2</param>
</process>
</data>


実行


mr-elephant:php shuzo$ php process.php xml ./process.xml
param1
param2


とりあえず必要なものだけを実装してみました。
もうちょいなんか工夫できそうな気がします。

というかGithubにあげてみたいと思ったのですが、うまくいってません。orz

※インデントが気持ち悪いところだけ修正しました。
※commandという名前はあまりよくないというご指摘を受けたので、修正しました。
どうせなので、微妙にリファクタリングを追加。

2011年12月19日月曜日

【php】クラスの継承メモ

phpでコード生成のプログラムを書くことがちょくちょく増えてきたので、インターフェイスとかを統一しておきたい。まずはクラスの書き方から勉強。


<?php
cmd($argc , $argv);
//コマンド
function cmd($num,$param){
if($num < 2){
echo "コマンドが入力されていません。\n";
return;
}
commandExec($param);
}

//コマンドの実行
function commandExec($arg)
{
switch($arg[1]){
case "test":
if(count($arg) < 3){ echo "引数が足りていません\n";return;}
$cmd = new TestCommand($arg[2]);
break;
default:
echo "設定されていないコマンドです。\n";
return;
}
$cmd->execute();
}

/***********************
*
* スーパークラス
*
**********************/
abstract class AbstractCommand{
protected $states;
abstract public function execute();
abstract public function toString();
}

/***********************
*
* 子クラス
*
***********************/
class TestCommand extends AbstractCommand
{
private $param;
public function TestCommand($param){
$this->param = $param;
}

public function execute(){

echo $this->param . "\n";
}

public function toString()
{
return "TestCommand";
}

}



これを実行すると。


mr-elephant:php shuzo$ php cmd.php test hoge
hoge


出力されました。上の内容でちょっとつまずいたところは、




class TestCommand extends AbstractCommand
{
private $hoge;
public function TestCommand($param){

$hoge = $param;
}

public function execute(){
echo $hoge . "\n";
}

public function toString()
{
return "TestCommand";
}

}


上のやり方だと出力されず、メンバ変数へのアクセスには必ず$this->hogeを使うとのこと。省略しちゃだめってことですね。