Translate

2012年3月11日日曜日

WebService::YahooJapan::WebMA

■Yahoo! 形態素解析APIを使ってみるメモ。
形態素解析APIを利用するにあたり、Yahooのアカウントと
AppIDを取得する必要があるので先に済ませておく。

1.Yahoo!のアカウントを取る。
https://login.yahoo.co.jp/config/login

2.どのページでもよいが、アプリケーションIDの登録をすませておく。
http://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html

#!/usr/bin/perl
use feature 'say';
use strict;
use warnings;
use WebService::YahooJapan::WebMA;
use utf8;
use Dumpvalue; my $d = Dumpvalue->new();
binmode STDOUT, ":utf8";

my $AppID = '上記で取得しておいたアプリケーションIDを記載する';
$WebService::YahooJapan::WebMA::APIBase = 
         'http://jlp.yahooapis.jp/MAService/V1/parse';

my $api    = WebService::YahooJapan::WebMA->new( appid => $ApiID);
my $result = $api->parse(sentence => '本日は晴天なり') or die $api->error; #解析したい文章を指定する

$d->dumpValue($result);

'ma_result' => HASH(0x7fa5bbb28ec8)
   'filtered_count' => 4
   'total_count' => 4
   'word_list' => ARRAY(0x7fa5bbb1ee98)
      0  HASH(0x7fa5bbb25838)
         'pos' => '名詞'
         'reading' => 'ほんじつ'
         'surface' => '本日'
      1  HASH(0x7fa5bbb25880)
         'pos' => '助詞'
         'reading' => 'は'
         'surface' => 'は'
      2  HASH(0x7fa5bbb25670)
         'pos' => '名詞'
         'reading' => 'せいてん'
         'surface' => '晴天'
      3  HASH(0x7fa5bbb24718)
         'pos' => '助動詞'
         'reading' => 'なり'
         'surface' => 'なり'
'xmlns' => 'urn:yahoo:jp:jlp'
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
'xsi:schemaLocation' => 'urn:yahoo:jp:jlp http://jlp.yahooapis.jp/MAService/V1/parseResponse.xsd'

2012年3月4日日曜日

perlの特殊変数のめも

気長にメモしていく予定。

変数内容
$$プロセスIDを返す
$,リストを出力時のセパレータ。デフォルトは空文字。
$.ファイルハンドルが読み込みを行った行番号が格納されている。ファイルの内容を1行ずつ読み込んでいる際に目的の行を見つけた際にそれが何行目か知りたい時などに利用
$0スクリプト実行時のパスを返す(絶対パスなら絶対パス。相対パスなら相対パス)
$]スクリプト実行した際のperlのバージョン
$|0以外を指定すると出力時のバッファーを行わなくなる。デフォルトは0

2012年3月3日土曜日

say関数

say関数を使いたい時どうすればいいのか。
というので、調べてみたら

use feature 'say';

だったり

use 5.10.0;

だったり

use feature ':5.10.0';

だったり

use 5.010;

いろいろあって違いがよくわからなかった。
で、featureプラグマの訳があったんで非常に理解しやすかった。
http://perldoc.jp/docs/modules/feature-1.11/feature.pod


つまり
use feature では、ピンポイントの機能追加を行い
use feature ':5.10.0'; では、追加機能が全て使えるようになる
use 5.10.0; は、上の別表記。
use 5.010; は、移植性の警告(?)を出さないための書き方ということなのね。

言ってしまえば、sayだけ使いたいんよ。
というのであるなら、追加機能すべて使える必要はなくて
use feature 'say';

で、OKってことになるのね。
で、おk?

Time:Piece

■日時の取得
#!/usr/bin/perl
use feature 'say';
use strict;
use warnings;
use utf8;
use Time::Piece;
binmode STDOUT, ":utf8";


my $t = localtime;

### 日時の表示
say $t;              #Sat Mar  3 14:53:37 2012
say $t->datetime;    #2012-03-03T14:53:37
say $t->datetime(
         date => '/', 
         T    => ' ',
         time => '-'
                );   #2012/03/03 14-53-37
say $t->strftime('%Y*%m*%d  %H@%M@%S');
                     #2012*03*03  14@53@37  注:UTF8フラグが落ちてます


### 年月日の表示
say $t->ymd;      #2012-03-03
say $t->ymd("/"); #2012/03/03
say $t->ymd("");  #20120303

say $t->year;     #2012
say $t->mon;      #3
say $t->mday;     #3


### 曜日の表示
say $t->wday;      #7
say $t->wdayname;  #Sat
say $t->wdayname(
   qw/日 月 火 水 木 金 土/
                ); #土

#wdaynameを何度も使うのなら
#デフォルトの曜日を変更してしまう
$t->day_list(qw/日 月 火 水 木 金 土/);
say $t->wdayname;  #土


### 時分秒の表示
say $t->hms;      #14:53:37
say $t->hms("-"); #14-53-37
say $t->hms("");  #145337

say $t->hour;     #14
say $t->min;      #53
say $t->sec;      #37


### 他
#閏年判定
say $t->is_leap_year ? "閏年" : "Not閏年"; #閏年

#最終日
say $t->month_last_day; #31


### 任意の時間を設定
$t = localtime->strptime('2000-01-01 12:00:00', '%Y-%m-%d %H:%M:%S');
say $t->datetime; #2000-01-01T12:00:00


### 時間の比較
my $BaseDate = localtime->strptime('20001122', '%Y%m%d');
my $TestDate = localtime->strptime('20111122', '%Y%m%d');
say $BaseDate < $TestDate ? "もうすぎたよ" : "まだ過ぎてないよ";
                  #もうすぎだよ

### 時間の加減・減算(秒単位で返ってくる)
my $date1 = localtime->strptime('20120101', '%Y%m%d');
my $date2 = localtime->strptime('20130101', '%Y%m%d');
my $days  = ($date2 - $date1) / (24 * 60 * 60);
say $days;        #366

ただ、一つ注意。
strftimeメソッドは、utf8フラグを落とすことに注意。

#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
use utf8;
use Devel::Peek;

my $t = localtime;
Dump $t->wdayname(qw/日 月 火 水 木 金 土/);
Dump $t->strftime('%Y年%m月%d日');

実行結果
SV = PV(0x7fd56b801170) at 0x7fd56b842708
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK,UTF8)
  PV = 0x105d08220 "\346\227\245"\0 [UTF8 "\x{65e5}"]
  CUR = 3
  LEN = 16
SV = PV(0x7fd56b801190) at 0x7fd56b842708
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK)
  PV = 0x105d06df0 "2012\345\271\26403\346\234\21004\346\227\245"\0
  CUR = 17
  LEN = 32

wdaynameメソッドの方には、UTF8フラグが残っているけど
strftimeメソッドの方には、UTF8フラグがないですよね。

上の例のように
binmode STDOUT, ":utf8";
して、標準出力する際にフラグを落とすようにしている場合
文字化けしちゃいます。

美しくないけど
binmode STDOUT, ":utf8"; するなら
use Encode;
say decode_utf8($t->strftimeメソッド);

のように内部にあるデータには徹底してフラグをつけるか

binmode STDOUT, ":utf8"; を使わないなら
use Encode;
say encode_utf8($t->strftime以外のメソッド);
say $t->strftimeメソッド;

とするしかないのかな…。


おまけ。
1日後、1ヶ月後を簡単に求めるのに
Time::Secondsを使う方法があります。

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use feature 'say';
use Time::Piece;
use Time::Seconds;

my $t = localtime;
say $t->ymd; #2012-03-03

$t += ONE_MONTH;
say $t->ymd; #2012-04-03

$t += ONE_MONTH;
say $t->ymd; #2012-05-03

$t += ONE_MONTH * 2;
say $t->ymd; #2012-07-03

Time::Secondsを利用すると以下の定数が使えるようになります。
ONE_DAY
ONE_WEEK
ONE_HOUR
ONE_MINUTE
ONE_MONTH
ONE_YEAR
ONE_FINANCIAL_MONTH
LEAP_YEAR
NON_LEAP_YEAR

後は、掛け算して加減算するなりすればよいですね。