2012年5月14日月曜日

Online Judge のようなものを作ってみる

最近、部活で後輩たちのテストを多くやるようになってきたので。
採点するのが結構大変かな〜と思って、AOJみたいな感じで問題作っておいて。
formからプログラムを送ると、コンパイルして実行までしてくれるシステムを作った。(もちろんUIはhoge)

さて、どうやって実装したか。

さすがに、プログラムが実行されるまでhttpのレスポンスが帰らないのはクソ実装すぎるので。

別のThreadを使って見ることにした。

Pythonで書いたのだが、モジュールがあったのですぐにかけた。

http://www.python.jp/doc/2.5/lib/module-threading.html
http://techno-st.net/2010/02/06/python-3.html

ここらへんを参考にすればいい。

次に、外部のプログラムの実行。
forkを考えたが、ちょっと調べてみると。

subprocessという標準ライブラリがあったのでそれを使ってみることにした。



import subprocess
subprocess.Popen(["echo", "hoge"]);

こんな感じで書けばecho hogeが実行される。

これは、stdinやstdoutの設定もできるし、そのコマンドが終わるまでプログラムが終わったりしないので、かなり便利だった。
一定時間まって、プロセスが終わっているかとかを確認して終わってなかったらKILLしてTLEにしてしまえばOK

一応、ソースをgithubに上げておきました。

https://github.com/higumachan/oknct_judge


2012年5月5日土曜日

PythonでFacebookAPIを使ってみよう

今日、昨日は主にFacebookへの認証周りを触っていました。もちろんPythonでです。
最終目標はTwitterの認証みたいな感じでFlask用の認証モジュールを作ることですね。

今日は認証がとれてデータを引っ張ってくることができたのでログを残します。

facebookもtwitterとほとんど同じですね。
違うのは認証ページからリダイレクトした先でさらにhttpアクセスしてアクセストークンを取得するというところです。
参考:FacebookのWallへポストするWebアプリ

簡単に手順を書きますと。

1.https://graph.facebook.com/oauth/authorize?client_id=[APP_KEY]&redirect_uri=[redirect_url]&scope=[permissions]にアクセスしてもらう。
2.redirect_uriのスクリプトでGETメソッドで与えられる。codeとSECRET_KEYを付け足してPOSTメソッドでアクセス。
3.access_tokenがかえってくる。

このような流れになってます。かえってきたaccess_tokenを保存しておけば毎回認証してもらわなくても大丈夫です。

認証をとった後のAPIへのアクセスなんですが、自分は最初pyfacebookというライブラリを使っていたのですが。ちょっと使いづらかったので、tweepyみたいな感じのライブラリfbpyを自分で実装してみました。一応githubにあげていますが、自分用なので、機能は自分が必要になったら実装するという感じですので、まだほとんど実装(ほぼ打ち込み業務)してません

github: https://github.com/higumachan/fbpy

これが、今日昨日やったことです。

fbpyの実装で関数を返す関数がとっても便利だって言う実感ができました。


2012年5月1日火曜日

WebベースのTwitterClientを作るまで

まず、どうして作ったのか。うちの学校では基本的に学内回線からTwitterできません(スマフォClient、テザリング、ポケットWiFiとか使えばいいんだけど)しかも、私はガラケーです。

最後の望みで合ったTabtterの仕様期間も切れてしまったので、作ってみようかなと思いました。

実装はPython+Flaskです

今回の実装は実装速度を重視したので、ステップの横に所要時間を書いて行きます。

  1. Twitterの認証:前々に紹介したFlaskでTwitter認証を行うモジュールで一瞬でした(10分)
  2. TimeLineの取得:Tweepyというライブラリを使って瞬殺。(5分)
  3. Tweetする:Tweepyで瞬殺(3分)
  4. もう取得したTweetはTimeLineに表示しない:取得したTweetIDの最大を持っておいて次に取得したときそのさっきのTweetIDの最大より大きい間でWhileを回す。(8分)
  5. 適当なHTMLを書く(8分)
  6. ajaxでTimeLineを更新するために適当なjavascriptを書く(8分)
  7. アイコンをtwitter.comから取得するのではなく、TwitterClientのサーバで通信を行いそれをクライアント側に返す(10分)
以上で最小構成のTwitterクライアントが完成です。
Timelineが確認できて、TweetをPOSTできるだけですが。所要時間が所要時間ですし。
まあ、いいかなってかんじです。
なぜ、WebベースのTwitterクライアントなら学内からできるのかというと。
twitter.comとの通信をすべて自前のサーバに任せてしまえば、学内のネットからは自前のサーバに接続するだけなので、その自前のサーバがブロックされない限りはブロックされないようになるというしくみです。なので、アイコンもサーバから取得するようにするのです。


http://pythonmongo-higumachan.dotcloud.com/

これが作ったクライアントです。
ちなみにデプロイで詰まってしまったのでデプロイでするのに実装時間の4倍かかってしまいました。

2012年4月22日日曜日

自前LISPのGCの実装

昨日の続きで自分でLISPを実装した話をしていきます。

今回の実装でいちばんバグが多かったのは今日話すガーベジコレクタ(GC)ですね

GCとは動的に取ってきたメモリ領域を使われなくなった部分だけ開放するというものです。

まず、このような処理系を実装するのは初めてなので自分は王道がわかりませんでした。

それなので、静的記憶域、動的記憶域(スタック)と関数テーブルの中を探索してここは使われてますよっていう、チェックをつけました。
しかし、これだけでは変数が参照として持っているものが開放されてしまうので、チェックしたところの中の値を調べて参照ならまたその中を調べるを再帰的に繰り返すことで、必要なところ全てにチェックがつきました。
そして、これをコンパクションつまり、詰めて行きます。

そして、実行したら動きました。

しかし、GCを動かしたあとにたまに不具合が。
テストをいっぱいしていると不具合が起こるところに大体のパターンが見えてきました。
そのパターンはだいたいGCを走らせる前にヒープ領域の最初の方に入っていた変数たちです。
そして、よくよく考えるとコンパクションしたあとに変数に入っているポインタの値がコンパクションする前の値になってましたorzこれを直すとうまくうごきました。

GCの実装はやっぱりポインタのいろんな使い方がわかったのでかなりやった価値があった気がします。

現在ではGC自体の動作が重いのでどうにかして最適化していきたいな〜。

2012年4月21日土曜日

[お勉強] 簡単なLISPのインタプリタを実装してみよう


LISPに入門したいな〜と思ってはや半年。なんか、言ってるだけな気がして嫌気が刺してきましたので。入門しようとLISPとGoogleで検索したら。
ちょっと変わったLISP入門 という、記事をみつけました。
この記事では、LISP 入門するついでに、LISPをC言語で実装しちゃおうという、ちょっとどころじゃなくかなり、変わった入門でした。

という、経緯で始めたLISPインタプリタの実装なんですが。その記事通りに書いても面白くないので。
データ構造だけチラ見して、自分でほとんど一から実装しました。

ひさしぶりに、C言語を使いました。(最近はもっぱらPython)次々とポインタを別のポインタにキャストしながら。実装していくこと。5時間程度。 

LISP の式をリストに落として簡単にevalすることができるようになりました。
とはいえ、まだほとんどの機能が実装されていません。(書き方が変な電卓みたいな感じ)

その後、四苦八苦しながらsetqを実装し、defunを実装しました。

スタックはグローバルと分けて考えてスタックから先に探索するという方法をとりました。

正直、スタックを考えたり、変数への束縛を考えたりするのは楽しかった。
今まで、書いてきたコマンドラインのプログラムの中で一番楽しいと言えるものかもしれない。

一応Githubに上げて有ります。
https://github.com/higumachan/easy_lisp
しかし、ファイル分割もしてないですし、ましてやプロトタイプ宣言すらめんどくさがってしまった書き捨てのコードです。

まだ、語ってないことにGC(ガーベジコレクタ)がありますが。長くなりそうなので。
これは、また明日書くことにします。

2012年4月7日土曜日

Flaskをmod_wsgiでデプロイ

今まで、避けていたwsgiでのデプロイを今日はやりました。

まず、Flaskの公式(http://flask.pocoo.org/docs/deploying/mod_wsgi/#installing-mod-wsgi)を見てApacheを設定してみる。

動かなかったので、http://zafiel.wingall.com/archives/2011110419102309.phpの設定を真似てみました。

そうしたら動きました。

しかし、Flask.gとPitがうまく動かなかった。
Pitの方はDocumentRootの関係かと思われる。

[まとめ]
できたこと
Flaskで書いたアプリがApache上で動いた。
出来てないこと
Pythonがエラー吐いて死んだ時のTraceがApacheのErrorLogに出てこない(print で出力した値は出てくる)
PitでのPassword管理が出来ていない。
Flask.gがまだうまく使えてない。

2012年4月5日木曜日

Flask用のTwitterOAuthモジュール作ってみました

現在TwitterAPIを使うサービスを作っているのですが。
そこで、問題になるのが認証なんですね。
毎回毎回結構めんどくさいです。

それなので、今回はFlaskでTwitterに簡単に認証するモジュールを作ってみました。

https://github.com/higumachan/flask_twitter
使い方は結構簡単にしたつもりで、
@app.route("/path/to")
@twitter_login
def view(api=None):
    pass
こんな感じでビューにデコレータを追加するだけで、Twitterに認証されてればそのビューに入り、認証されていなければ認証画面に入る。という感じです。
認証からのCallbackになってるビューにこのように書けばOKです

@app.route("/path/to")
@twitter_callback
def view():
    return (make_response("ようこそ"))

今回初めてデコレータを使ったのですが、今まで何に使うのかわからなかったのですがたしかに便利だな〜って感じがありました。

TwitterのサービスをFlaskで作るときは使ってみてください。