Home > 2009年03月
2009年03月
ブログの文字色を濃くしました
- 2009-03-20 (Fri)
- お知らせ
最近目が悪くなってきたのか、自分でも見づらかったので…。
デザインをできるだけ壊さないよう、色合いはそのままで暗くした。
(16進数の各桁を2ずつ減らすという微妙な作業によって)
color: #8c8c8c; /* default */
color: #6a6a6a; /* dark */
こんな感じ。
若干ダサくなったけど、まぁしかたないでしょう。
※ テンプレート作者さん、すいません。。。
初めてのPerl:ディレクトリ内のhtmlファイルに含まれる英単語数を数える(ついでにgoogleのapiで翻訳)
- 2009-03-07 (Sat)
- Perl
(ようやく)Perl始めました。
ちょっと前から入門書とかは読んだりしてたんだけど、
発売前から楽しみにしてた、
が、あまりにもわからなくて凹んだので。
やっぱプログラミングはコーディングして覚えないとね。
ちょうど記事タイトルのようなことがやりたかったこともあり、Perlで頑張ってみました。
というわけで、以下がPerl入門~サンプルコードによるPerl入門~(便利すぎ!!)を参考に作ったソースです。
ディレクトリ内htmlの英単語をカウント
ちなみに環境は、VMWare Playerでお手軽にVista上でLinux(Ubuntu) - Born Neetで入れたUbuntu。
perlやるならやっぱUnix系かな、と。(perlもcpanも元から入ってて楽だったし)
#!/usr/bin/perl
use strict;
use warnings;
my @files = glob '*.html';
my %count;
foreach my $file ( @files ) {
open( my $fh, '<', $file ) or die "Can't open $file: $!";
my $content;
{
local $/ = undef;
$content = readline $fh;
}
$content =~ s/<head>.*<\/head>|<[^>]+?>//gs;
my @words = split( /\W+/, $content );
foreach my $word ( @words ) {
if( $word ) {
$count{ lc $word }++;
}
}
}
my @sorted = sort { $count{ $b } <=> $count { $a } } keys %count;
foreach my $key ( @sorted ) {
print $key ."\t" . $count{ $key }, "\n";
}
Google Language APIで翻訳
CPAN・モジュールのお勉強を兼ねて、Google AJAX Language APIで翻訳してみる。
参考→Google AJAX Language API で翻訳する/楽
#!/usr/bin/perl
use strict;
use warnings;
use WebService::Simple;
my $api = WebService::Simple->new(
base_url => "http://ajax.googleapis.com/ajax/services/language/translate",
response_parser => "JSON",
params => {
v => '1.0',
langpair => 'en|ja',
},
);
sub translate {
my $response = $api->get({
q => shift,
});
return $response->parse_response->{ responseData }->{ translatedText };
}
print translate('test'); # 試験
これを1つ目のコードとマージして、
foreach my $key ( @sorted ) {
print $key ."\t" . translate($key) . "\t" . $count{ $key }, "\n";
sleep 1;
}
みたいにすれば英単語を数えつつ、翻訳も出来る。
(googleに怒られないように一応1秒待つようにした)
結果と微調整
結果がこちら↓
$ head -20 analyze.txt the その 7280 quot quot 4476 a 1つの 4280 to ?へ 4120 is なる 3192 of の 3088 and および 2367 it それ 2073 that あの 1902 this この 1804 in インディアナ 1627 function 関数 1604 be 存在する 1322 can ?できる 1165 are なる 1158 for ?のために 1093 you あなた 1044 not ?でない 901 The その 897
…とここで、大文字/小文字を区別しちゃってることに気づく。
(例:theとThe)
そう何度もgoogleにリクエストを送りたくないということで、
以下のような急造スクリプトで対応。
(全部小文字にして単語数を合計)
#!/usr/bin/perl
use strict;
use warnings;
open( my $fn, '<', 'analyze.txt' ) or die '$!';
my %lower;
my %ja;
while ( my $line = readline $fn ) {
my ( $en, $ja, $c ) = split( "\t", $line );
$lower{ lc $en } += $c;
$ja{ lc $en } = $ja;
}
foreach my $word ( sort { $lower{ $b } <=> $lower{$a} } keys %lower ) {
print $word . "\t" . $ja{$word} . "\t" . $lower{$word} . "\n";
}
微調整した結果がこちら↓
ちゃんとtheとTheが合計されてる。
スクリプトには無駄が多そうだけど、初めだし、期待通り動いてるのでまぁよしとする。
$ head analyze2.txt the その 8177 a 1つの 4499 quot quot 4476 to ?へ 4240 is なる 3198 of の 3106 and および 2439 it それ 2403 this この 2249 that あの 1944
つまづいたとこ
perlcodesampleがかなり充実してたので、コーディング自体は特に困らなかった。
一番時間かかったのはCPANのモジュールを使うところ。
以下その時のメモ。
まずは、
$ cpan
で設定。
全部Enter連打で。
Enterで駄目なところは地域・国・サーバの指定ぐらいなので、そこは適当に番号で選ぶ。
設定が終わると、プロンプトが
cpan>
になるので
cpan> install WebService::Simple
等、インストールしたいモジュール名を入れる。
あとは依存してるモジュールとかも勝手に入れてくれるので、(またもや)Enter連打で答えていく。
インストールが終了したら、
cpan> q
で終了。
とここまでは特に問題はなかった。
が、モジュールを使用したファイルを実行すると、
Can't locate WebService/Simple.pm in @INC
と怒られた。
(いろいろ苦労しつつ)結局、
$ perl -I/home/ユーザ名/.cpan/build/WebService-Simple-0.15/lib ファイル名.pl
でいけたけど…
なんか面倒くさい、本当にあってるのか?
2009/03/08 15:40 追記
やっぱ間違ってました。
perlcodesampleさんからコメントもらった(ありがとうございます!)ので改めてやり直してみると、
テストで、
# Failed test 'param is uri escaped' # at t/01_escape.t line 16. # got: '?param=%E7%8C%AB' # expected: '?param=' # Looks like you failed 1 test of 2.
なんてエラーが出てた。
ダメもとで、'param is uri escaped'で検索したら、
URI::Escapeってモジュールがあったので、これだ!と思ってinstall。
sudo cpan cpan> install URI::Escape cpan> install WebService::Simple
無事、
perl ファイル名.pl
だけでいけるようになりました。
モジュール自体に必要なものは自動でインストールされるけど、
テストで使ってるやつはそうじゃないってことなのかな?
やっぱわからないことだらけだなー。
頑張ろーっと。
2009/03/08 16:00 追記2
インストールされた場所を確認しようとしたら、
perldoc -l WebService::Simple You need to install the perl-doc package to use this program.
なんてエラーが出るので、
sudo aptitude install perl-doc
とかやる必要有り。
perldoc -l WebService::Simple /usr/local/share/perl/5.8.8/WebService/Simple.pm
Ubuntu(debian)特有っぽい。よくわかんないけど。
ActionScript再挑戦!Flexで人工無脳作ってみた
- 2009-03-05 (Thu)
- Flash・Flex・AS
2009/06/20 20:10
誤字脱字修正。
2009/03/06 22:45
htmlのソースとプロジェクトファイル一式を追加しました。
たぶん、今までで一番長文です。
1年以上前に書いた、
・ Hello, Flash!:ActionScriptを初めて使ってみたらお絵かきが簡単にできてびっくりした - Born Neet
は今だに僕のブログで一番の人気記事です。
(HolyGrailさんのおかげでしょうが…)
にもかかわらず、それから一年以上ASの話題を扱わないという体たらく。
(地味に勉強してたりはしたんですが、記事にするまでにはいたりませんでした。)
というわけで改めて学びなおすべく、新しい言語の学習にはもってこい(?)の人工無脳を作ってみました。
以下に手順をメモしますので興味があればどうぞ。
ソースのライセンスも(使用ライブラリに合わせて)修正BSDにしとくのでご自由に。
前やった時は、FlexのFの字もわかってなかったのでたいした説明はできませんでしたが、
今回は本読んだり、(だいぶ前ですが)セミナーに行ったりもしてたのでいくらかはマシだと思います。
Flexとは
Flexは、Flashの技術を利用したリッチインターネットアプリケーション(RIA)です。
Flexならデザインセンスのカケラもない僕でも、プログラミングするだけでFlash Player上で動くアプリケーションを作ることができるのです。
と、僕は理解してます。
まぁ細かい定義なんかはどうでもよくて、FlashPlayerがあればどこでも同じように動く、
つまり、「Firefoxで開発→IEで確認→動かない→直す→Firefoxで変に」みたいなことをしなくて済むのです。
ということで僕は勝手にFlexはRIAの本命なんじゃないかと思ってます。
準備
まずは環境を整えます。
やったのは半年以上前なので抜けてるかもしれません。
開発には、FlashDevelopを使います。
補完がないときついので。(テキストエディタでJavaを開発するぐらいのしんどさです)
というわけで、以下のサイトあたりを参考にFlex SDKとFlashDevelopを(ないならJavaも)インストール。
(自分が参考にしたサイトは忘れちゃったので適当に検索しました。)
・ Adobe Flex SDK超入門 (treasuring misc.)
・ フリーのFlash統合開発環境 FlashDevelop (+flex 3 SDK)を入れてみました:■ 音楽方丈記 ■
他にも情報は山ほどあるのでここは省略。
Flexプログラミング入門
Flashはどうやって作ってるのかさっぱりわかりませんが、
FlexはWebプログラマにとって非常にわかりやすい構造です。
(カッコ内参照)
作成するファイルは以下の3つ。
・ mxml(htmlの役目)
・ ActionScript(JavaScriptの役目)
・ CSS(そのまま)
HTMLベースのアプリと同様に、
mxmlで構造、ASでイベント等を設定、CSSで装飾します。
さらにASとJSは型とclassがあること意外ほとんど同じなので、
mxmlだけ覚えればもう何でも作れちゃうのです!
(実際は以前の僕の記事のようにmxmlなしでも作れますが…)
FlashDevelopのプロジェクトの作り方
さて、そろそろ飽きてきましたが。。。
FlashDevelopは高機能なので初めて使う時若干とまどいます。
特に新規プロジェクト作成の選択肢が多すぎる!
ってことで僕の作成手順を書いときます。
1. AS3のEmptyProject(なんか2個あるけど上の方)を選択
・ Nameは適当(一応ラクダ文字が規則みたい)
・ packageは空で
これで余計なものが何もない空のプロジェクトが作られます。
2. Projectの箱を右クリックしてmxmlを追加
さらに
・ 追加したmxmlを右クリックしてAlwaysCompileにチェック
・ プロジェクトのプロパティ(右クリック or メニューから)で
「No output~」のチェックを外し、ファイル名を適当に入力
FlashDevelopがちゃんとインストールされていれば、
これでコンパイルでき、Flashでおなじみのswfファイルが作成されるはずです。
(参考サイトにもありますが、External Playerの設定大事)
あとはASなりCSSなりサブのmxmlなりをガシガシ追加していくだけです。
SWFObject
もう駄目だ…長文すぎる…。
というわけで、ソース以外はこれで最後です。
Flashを公開する時はHTMLに埋め込むことになります。
しかしこれが、objectタグやらembedタグやら実にややこしい。
そこで、swfobjectです。
このライブラリを使えばid指定とjs1行で済みます。
詳しくは、
・ 八角研究所 : FlashをHTMLに貼るライブラリ swfobject 2 を使う
・ SWFObject v2.0 ドキュメント日本語訳 : Media Technology Labs (MTL) : メディアテクノロジーラボ ブログ
・ nondelion.com - 続・swfobject で flash を Window 内に全画面表示
等をどうぞ。
Flexな人工無脳
ようやく本題です。
もう説明する気力は残ってないのでコメントを参照してください。
僕の試行錯誤の結果です…。
動くサンプルはここに置いときます→Flexで人工無能 - tnantoka.net
(はじめは空っぽですが、会話を覚えていきます。
またstudyタブからテキストをaddすれば賢くなるかもしれません。)
プロジェクトファイル一式も置いとくのでどうぞ。
Main.mxml
画面構造
<?xml version="1.0" encoding="utf-8"?>
<!--
Applicationにwidth,heightを設定すれば、-config.xmlをいじらなくても大きさ指定できる
creationCompleteはwindow.onload的存在(as内からは設定できないので属性で)
-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
<!-- as,css外部ファイル化 -->
<mx:Script source="init.as"/>
<mx:Style source="style.css"/>
<!-- 大枠 -->
<mx:Panel width="100%" height="100%" title="Flexで人工無脳" horizontalAlign="center">
<!--
タブ切り替え
creationPolicy="all"にしないと初期化時にイベント設定できない
-->
<mx:ViewStack id="viewStack" width="100%" height="100%" creationPolicy="all">
<!-- 会話画面 -->
<mx:VBox label="talk" horizontalAlign="center">
<mx:HBox width="70%">
<mx:TextInput width="90%" id="msgInput" />
<mx:Button label="send" id="sendButton" />
</mx:HBox>
<mx:TextArea width="70%" height="85%" id="historyArea"></mx:TextArea>
</mx:VBox>
<!-- 学習画面 -->
<mx:VBox label="study" horizontalAlign="center" styleName="study">
<mx:TextArea width="70%" height="87%" id="sourceArea"></mx:TextArea>
<mx:HBox width="70%">
<mx:Button label="init" id="initButton" />
<mx:Spacer width="100%"/>
<mx:Button label="add" id="addButton" />
</mx:HBox>
</mx:VBox>
</mx:ViewStack>
<!-- タブメニュー(各要素のlabelがタブに) -->
<mx:LinkBar dataProvider="{viewStack}"/>
</mx:Panel>
</mx:Application>
init.as
イベントを設定したり、Munouクラスを使ったり。
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import mx.events.FlexEvent;
import mx.rpc.http.HTTPService;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
// グローバル使わないために関数内で処理
private function init():void {
var munou:Munou;
// テキストを読み込んで学習
// XMLHttpRequest同様に使える
var http:HTTPService = new HTTPService();
http.url = 'test.txt';
http.resultFormat = 'text'; // デフォルトはXML
// 成功
http.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void {
// munou = new Munou(event.result as String);
munou = new Munou(''); // 今回は白紙で
});
// 失敗
http.addEventListener(FaultEvent.FAULT, function(event:FaultEvent):void {
Alert.show(event.fault.faultString);
});
http.send();
// sendクリックで話しかける
sendButton.addEventListener(MouseEvent.CLICK, send);
// エンター押下にも同じイベント設定
msgInput.addEventListener(FlexEvent.ENTER, send);
// 初期化
initButton.addEventListener(MouseEvent.CLICK, function(event:Event):void {
//
munou.init(sourceArea.text);
sourceArea.text = '';
});
// 覚えさせる
addButton.addEventListener(MouseEvent.CLICK, function(event:Event):void {
if (sourceArea.text) {
munou.learn(sourceArea.text);
sourceArea.text = '';
}
});
// 話しかける
function send(event:Event):void {
var msg:String = msgInput.text;
// ちょっとだけhtmlが使える
historyArea.htmlText += '<p>あなたの発言:<br/>\t' + msg + '</p>';
historyArea.htmlText += '<p><font color="#0000ff">munouの発言:<br/>\t' + munou.response(msg) + '</font></p>';
msgInput.text = '';
// スクロールバーを最終行に設定
// (遅延実行?しないと更新前の位置になる)
callLater(function():void {
historyArea.verticalScrollPosition = historyArea.maxVerticalScrollPosition;
});
}
// かぎカッコ内のテキストを抽出(不使用)
function getTalk(text:String):String {
var talk:Array = text.match(/「[^」]+?」/g);
for(var i:int = 0; i < talk.length; i++) {
talk[i] = talk[i].replace(/[「\s 」]+/g, '');
}
return talk.join('\n');
}
} // init
Munou.as
人工無脳(簡易形態素解析+マルコフ連鎖)で会話するclassです。
/**
* 人工無脳(簡易形態素解析+マルコフ連鎖)で会話するClass
*/
package {
// import org.coderepos.text.TinySegmenter; // CodeRepos
import uwi.tinysegmenter.TinySegmenter; // SparkProject
// mxml名と被るとダメ
public class Munou {
// 文頭・文末識別子
private const START:String = '__START__';
private const END:String = '__END__';
// 初期化テキストを一応保存
private var text:String;
// 形態素解析マシン
private var segmenter:TinySegmenter;
// 学習した結果
private var dic:Object;
// コンストラクタ
public function Munou(text:String) {
this.text = text;
segmenter = new TinySegmenter();
init(text);
}
// 初期化
public function init(text:String):void {
dic = {};
learn(text);
}
// 学習
public function learn(text:String):void {
if (text) {
// スペース・タブは1字に圧縮
// 改行で区切る(スペース・タブは残したいので\sは使わず)
// そのほかの記号は無視
var a:Array =
text.replace(/([ \t])+/g, '$1')
.split(/[\r\n]+/);
// Vistaならtraceログは以下に
// C:\Users\<user>\AppData\Roaming\Macromedia\Flash Player\Logs
// trace(a.join(','));
for (var i:int = 0; i < a.length; i++) {
var b:Array = morph(a[i]);
trace(b.join('|'));
b.unshift(START);
b.push(END);
for (var j:int = 0; j < b.length - 1; j++) {
var s:String = b[j];
if (dic[s]) dic[s].push(b[j + 1])
else dic[s] = [b[j + 1]];
}
}
}
}
// 形態素解析
private function morph(text:String):Array {
return segmenter.segment(text);
}
// マルコフ連鎖で文章作成
private function markov(text:String):String {
if (!dic[START]) return '';
var s:String = dic[START][Math.floor(Math.random() * dic[START].length)];
var r:String = '';
while (s != END) {
r += s;
// 文末っぽい記号が出ても終了
if (s.match(/[。!!??]/)) break;
s = dic[s][Math.floor(Math.random() * dic[s].length)];
}
return r;
}
// 応答
public function response(msg:String):String {
var func:Function;
learn(msg);
// 今回はマルコフのみで
// switch(Math.floor(Math.random() * 10)) {
// 1/10の確立でオウム返し
// case 0:
// func = echo;
// break;
// 1/10の確立で定型応答
// case 1:
// func = random;
// break;
// その他はマルコフで
// default:
func = markov;
// }
return func(msg);
}
// オウム返し(不使用)
private function echo(msg:String):String {
return msg;
}
// ランダム応答(不使用)
private function random(msg:String):String {
var a:Array = [
'',
];
return a[Math.floor(Math.random() * a.length)];
}
// 初期化テキスト表示(不使用)
public function getText():String {
return text;
}
} // class
} // package
style.css
見た目を調整。
htmlほど自由には設定できません。
@charset "UTF-8";
Application {
background-color: #fff;
/* width: 300px; 効かない */
}
Panel {
/* width: 100%; %指定はエラー */
/* padding: 10px; 効かない */
padding-top: 20px;
padding-bottom: 20px;
}
HBox {
/* text-align: center; TextInputの中身がセンタリングされちゃう */
padding-top: 10px;
padding-bottom: 10px;
}
.study {
padding-top: 10px;
}
index.html
swfを全画面表示
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Flexで人工無脳 - tnantoka.net</title>
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" type="text/css" href="style.css" media="all" />
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF('Munou.swf', 'swfArea', '100%', '100%', '9.0.0');
</script>
<style type="text/css">
/* for Firefox */
html, body {
height: 100%;
}
html {
overflow: hidden;
}
/* common */
body {
margin: 0;
}
</style>
</head>
<body>
<div id="swfArea" style="width: 100%; height: 100%;">
</div>
</body>
</html>
読んだ本
だいぶ前に読んだ時はイマイチと思ったんだけど、
(AIRプログラミング入門と内容を使い回しすぎだし)
今回作るにあたってリファレンスとして結構役に立った。
初Flexのお供に是非。
ホントはFlex3.0SDKで学ぶActionScript3.0入門が欲しかったんだけど、
どこにもないので(発売後1年足らずなのに…)しかたなく、同じくFlex SDK(Builderではなく)で作るこの本を購入。
(安さにつられたわけじゃ…)
プログラミング初心者用の本のため、他言語の経験者にはあまり向かない。
僕はE4Xを触ったことがなかったので多少はためになりました。
(本は対象読者を見てから買いましょう、ですね!)
あと、ところどころに、ん?と思う説明が。。。
関数名だけで利用される関数をクロージャともいいます(p.168)
…いいません!(笑)
とかね。
その他参考
・ TextArea自動スクロール
FirefoxのTextAreaと同じくtextを追加するとスクロールバーが先頭に戻っちゃう対策。
・ [Air/Flex]ViewStackの落とし穴 - 秘密結社ぎゅう☆ぎゅう倶楽部
スムーズな画面遷移と引き換えにイベント設定ができなくなるとか…。
・ たまご日記(別館) [flex] テキストの改行が余分に付く
改行の扱いにわりと苦労させられました。
・ /air/TLife/src/uwi/tinysegmenter/TinySegmenter.as - Spark project
・ /lang/actionscript/as3tinysegmenter/src/org/coderepos/text/TinySegmenter.as -- CodeRepos::Share -- Trac
TinySegmenterのAS移植版。
僕はなんとなくSparkProjectの方を使ってます。
GoogleのTwitter初発言をJavaScriptで読めるように
- 2009-03-01 (Sun)
- JavaScript
遅い(※)。しかもしょうもない。
が、自分が読むために作っちゃったので公開しとく。
※ googleがじゃなく僕がブログのネタにするのが…ね、一応。
2進表記を文字に直すのは、
String.fromCharCode(parseInt('01100110', 2)); // f
でOK。
というわけで、Googleの発言を読めるようにしましょう。
できました。
答えは…
最近何かと話題のGoogle日本のトップ画面からいつのまにか消え去ったあの機能です。
あぁあのシンプルな画面がなつかしい。
一応ソース
<textarea id="decodeGoogle" cols="30" rows="3"></textarea><br />
<input type="button" value="変換" onclick="(function(){
var chars = document.getElementById('decodeGoogle').value.split(/\s/);
for(var i = 0; i < chars.length; i++) {
if (!isNaN(chars[i])) chars[i] = String.fromCharCode(parseInt(chars[i], 2));
else chars[i] = chars[i] + ' ';
}
document.getElementById('decodeGoogle').value = chars.join('');
})()" />
以上です。
Home > 2009年03月



思わず続編を探してしまいました。
これからFlexを触る方へ