nemo_kazのメモ [Groovyライフ]

2012-01-20 [Groovy] docx renamer Word文書のファイル名を タイトル+最終更新日

多様なサブディレクトリに置かれたワード文書を、このスクリプトを起動した地点に移動させ、かつ

ファイル名を、

"元の名前.docx"

から

"元の名前_メタデータに書かれたタイトル名_最終更新日.docx"

に変更するスクリプトです。

この操作は、非可逆に、大量に操作するので、元の文書はバックアップを取って様子を確認してから使ってみてください。

// ワード文書名に、タイトルと変更日のメタタグを追加する。
// 変更例 : 文書13.docx --> 文書13-Groovyでお掃除-20120117.docx

startDir = "."

new File(startDir).eachFileRecurse { file ->
  if (file.isFile() && file.name.endsWith("docx")){
     new AntBuilder().unzip(src: file, dest:'/OUTPUT') {
        patternset {
           include(name: '**/core.xml')
        }
        mapper(type: 'flatten')
     }
     println file
     docxcore = new groovy.util.XmlParser().parse("/OUTPUT/core.xml")
     title =  docxcore.toString().replaceAll(/(.*title\[attributes\=\{\}; value=\[)([^\]]*)(\]\], \{http:\/\/purl.*)/)  {m0,m1,m2,m3->m2 }
     title = title.tr(':/ ','___')

     modified =  docxcore.toString().replaceAll(/(.*\}modified\[attributes\=\{\{http.*W3CDTF\}; .*value\=\[)(20[^\]]*)(Z\]\]\].*)/) {m0,m1,m2,m3->m2 }
     modified = modified.replaceAll(/(.*)(T..:..:..)/) {m0,m1,m2 -> m1}
     modified = modified.replaceAll(/(\d+)\-(\d+)\-(\d+)/) {m0,m1,m2,m3 -> m1+m2+m3 }

     targetName= file.name.replaceAll('\\.docx','') +'-'+ title +'-'+modified +'.docx'
     println file.name + " renamed to " + targetName
     file.renameTo(new File((targetName )))  
  }
}

2011-12-16 [Groovy] 自分のPCにある写真をPicasa webに丸ごとアップ

自分PCにあるjpg写真サブディレクトリーの階層ごと丸ごとアップロードます

G* Advent Calendar 2011 17日目のネタです。  #gadvent2011

特にGroovyの新技術を使うこともなく、あくまて日用の小道具として、目的志向Groovyを活用したいと思います

picasawebストレージGoogle+に参加するとほぼ容量無制限となるので、

公開するかどうかは、後でアクセス権の設定の時に考えるとして自分PC写真を全てPicasaに保存します

目的は洪水対策ですね、自分の家のPCが全壊してもアルバム保全したいと思います

前提として使うアプリケーションGladinet Cloud Desktopです。

これによりPicasa web サービスドライブとしてPCマウントして見ることができます

したがって動作OSWindowsです。

Picasa webサービズがドライブとして見えているのだから

ここに一気に xcopyrobocopy で一気にコピーできるかというと、Picasa web には制約があって、サブディレクトリーは一段までです。

例えば

c:/趣味/つり/伊豆/船1.jpg

という深いディレクリーにある画像ファイルはそのままでは送れません、それを

c:¥趣味_つり_伊豆¥舟1.jpg

という風にディレクトリー名をひとつの長いものに変えて送る必要があります

ここでは特にPicasaWebサービスAPIとかは使っていなのでPicasa以外の似たようなサービスにも適用できると思います

以下のスクリプトは、自分の持っているjpgをまるごと複製するので、動かす頻度がとても少ないのでハードコードしまくりです。

コピー先のPicasaディレクトリーは、ルートが z:/GooglePicasa という設定になっている前提です。

またこのスクリプト自体は、複製元の写真の配置してある場所ルートで起動します

sleep で相当遅くなってますが、これは Gladinetフリー版は、一日あたりの転送数に、制限がある為です

まったりPCをつけっぱなしにて動かすことが前提です。

多分Gladinet側の問題たと思いますが、何やら動作が不安定です。

量的にGladinetに負荷をかけすぎているのかもしれません。

def  targetDrive="z:\\GooglePiasa\\"  // Gladinet で設定したPicasa Webサービスのroot directory

File.metaClass.copy = { String destName -> 
  if(delegate.isFile()){
    new File(destName).withOutputStream{ out ->
      out.write delegate.readBytes()
    }
  }
}

new File(".").eachFileRecurse { file -> 
  if(file.isFile() && file.name.endsWith('.jpg')){
    curName = file.getPath().replaceAll(/.\\(.*)/) {m0,m1 -> m1}
      newName = curName.reverse().replaceFirst("\\\\", "----").reverse()
      newName = newName.replaceAll("\\\\", "_")
      newName = newName.replaceAll("----", "\\\\")
      newFile = new File(URLDecoder.decode(newName, "UTF-8"))
      println "現行ファイル名: "+curName
      println "新規ファイル名: "+newName
      
      subDir = newName.toString().replaceAll(/\\.*$/,"")
      if (subDir && subDir.length() +2< newName.length() ) { 
        targetDir = new File(targetDrive+subDir)
          if (!targetDir.exists()) {
             println "Subdir作成:" + targetDrive+subDir
             new File(targetDrive+subDir).mkdir();    //make folders   
             Thread.sleep(1000*60)
          }
      }
      new File(curName).copy(targetDrive+newName)
      Thread.sleep(1000*60)
  }
}

すみませんいまいち安定動作していません、うーん。

2011-02-20 [Groovy][Twitter] 固定ハッシュタグ複数定点観測用追跡器作りました

[Groovy][Twitter] 固定ハッシュタグ複数定点観測用追跡器作りました

#devsumi とか、#jawsug とか、ずっと追跡し続けたい固定ハッシュタグは、いくつかあるものです。

自分PDAデバイスそのものでハッシュタグを追跡すると、途中を見落とししたり、電池切れで追えなくなったりします。

このような問題があるため、できれば追跡そのものは自宅のマシンで無人で行い、その結果を随時PDAで閲覧する方式の

方が便利が良いと思います。また、デブサミのような大規模なセミナーだと複数のハッシュタグを追わないと追いつかないケースもあり、

複数のハッシュタグを同時に記録し続けたいこともあります

そんな目的のために複数固定ハッシュタグ追跡器作りました

複数のハッシュタグを追跡し続けてログを付けます


準備:

TAGS.txt という、事前に追跡しておきたい、お好みのハッシュタグテーブルを作ります、1件1行です。

実は、登録する単語は、ハッシュタグである必要はなく、また日本語でもOKです。TwitterStream API検索する場合は、ハッシュタグのみが可能です、逆に通常の検索場合は、日本語でも何でも探せますが、その代わり、即時性がありません、スピードと多様性はトレードオフですが、ここでは、記録性を優先するので、通常の検索で追っています、従って5分から10分程度の遅延を伴います

動かし方: TAGS.txt と同じディレクトリーで HashTagChaser.groovyを動かします。

すると#jggug.log といった名前ログファイルが作られます

この結果をPDAでコンファレンス会場などで閲覧すればOKです。

で、この結果を外からどうやって見るかですが、簡単なことですが単にDropboxディレクトリー内で動かすだけです。

巨人の肩の上に立つ訳です。

Dropboxの閲覧はPCでもiPhoneでも可能です。

Groovyインスコするのはイヤという人のために、独立したjar版も作っておきました。

HashTagChaser.jar

こちらは、Javaだけあれば単独で動きます


また、Dropboxアカウントをお持ちでない人は、よかったらこちらからアカウント取得してください。

http://db.tt/8BiuAAb

招待ありでアカウント作成すると、紹介者と招待された人の双方に、初期値の2Gに、プラスで250MB の容量追加が与えられます。招待者の私(nemo10)も250MBメリットがあります

TAGS.txt ファイルの例 (単なる単語でもOK)

#jggug
#javareading
#devsumi
アイマス

それぞれのタグ名に応じて #jggug.log とか #javareading.log などのログが時々進んでいきます


実行コード HashTagChaser.groovy 
>|groovy|
import static groovy.util.GroovyCollections.combinations
import groovy.util.Eval
import groovyx.gpars.GParsExecutorsPool

// 検索単語エンコード
String.metaClass.encodeIt = { ->
	return URLEncoder.encode(delegate,"UTF-8").replaceAll(/\.log/,'')
}
assert "ツイッター.log".encodeIt() == "%E3%83%84%E3%82%A4%E3%83%83%E3%82%BF%E3%83%BC"

// 発言番号を取得
String.metaClass.getNum = { ->
	if (delegate ==~/.*tag.*search.*/) {
		//println "発言番号取得 " + delegate.replaceAll(/.*:([0-9]+)/, '$1')
		return delegate.replaceAll(/.*:([0-9]+)/, '$1')
	} else {
		return delegate
	}
}
assert "tag:search.twitter.com,2005:16060673193".getNum() == "16060673193"

// 発言IDを取得
String.metaClass.getID = { ->
	if (delegate ==~/.*\(.*\)/) {
		//println "ID取得 " + delegate.replaceAll(/([^ ]+) \(.*/, '$1')
		return delegate.replaceAll(/([^ ]+) \(.*/, '$1')
	} else {
		return delegate
	}
}
assert "nemo_kaz (kazuo nemoto)".getID() == "nemo_kaz"

// 日本語チェック
String.metaClass.isKana = { ->
	if (delegate ==~/.*[あ-んア-ン].*/) {
		return "OK"
	} else {
		return "NG"
	}
}
assert "tag:search.twitter.com,2005:16060673193".getNum() == "16060673193"

//////////////////////////////////////

def loggers=[]
def file = new File("TAGS.txt")

file.eachLine{logname -> loggers.add (new Agent(logname+".log")) }

for (;;){
	try {
		loggers.each {clazz -> clazz.logIt() }
		Thread.sleep(1000*60*8)
	} catch (Exception e) { println "Exception"+e }
}

class Agent{
	String url
	File fhandle
	def counter
	def logname
	Agent(String input) {
		logname=input
		fhandle = new File(input)
		//fhandle.write("aaa\n")
	}
	def logIt() {
		def feed = null
		print " "
		def  atom2 = ("http://search.twitter.com/search.atom?q="+logname.encodeIt()).toURL().text
		feed = new XmlSlurper().parseText(atom2)
		feed.entry.collect{it}.reverse().each {
			if (counter < it.id.toString().getNum().toLong()) {
				counter = it.id.toString().getNum().toLong()
				if (it.title =~ /^RT/) {} else {
					println "■"+it.title +"  "+it.author[0].name.toString().getID() 
					fhandle.append("■"+it.title +"  "+it.author[0].name.toString().getID()+"\n" )
				} //RTは割愛
			} else {
				Thread.sleep(1000*5)
			}

		}//each
	}//logIt()
} //class Agent

2010-09-21 [Groovy] Twitterの特定キーワードを追跡し続けるスクリプト

TwitterStream APIを使うと、簡単に特定ハッシュタグリアルタイム

追跡できるわけですが、その代わり、漢字Stream APIで追跡することはできません。

ハッシュタグ漢字であったり、ハッシュタグ以外も追跡したい場合は、通常の検索機能を使うと、追跡できますが、今度は逆にStreamではないので、動きが緩慢になります。

漢字は追えないとあきらめてしまえばかまいませんが、やはり汎用な物を持っておきたいので作っておきました。

即応性の要求される、2時間程度のコンファレンスの追跡はStream APIが良いわけですが、

複数日にわたるイベントの追跡は検索APIを使ってもかまわないといえます。

このような仕様なので使いどころがないと思っていましたが、ちょうどJavaOneが開催されていて、複数日ずーっとそれを追いたい訳なので、#javaonejp のハッシュタグで追跡し続けています。

記録性の為なのでテキスト出力の方が便利かなと思っています。


@Grab('net.homeip.yusuke:twitter4j:[2.0,)')
import groovy.xml.Namespace

// 発言番号を取得
String.metaClass.getNum = { ->
	if (delegate ==~/.*tag.*search.*/) {
		//println "発言番号取得 " + delegate.replaceAll(/.*:([0-9]+)/, '$1')
		return delegate.replaceAll(/.*:([0-9]+)/, '$1')
	} else {
		return delegate
	}
}
assert "tag:search.twitter.com,2005:16060673193".getNum() == "16060673193"

// 発言IDを取得
String.metaClass.getID = { ->
	if (delegate ==~/.*\(.*\)/) {
		//println "ID取得 " + delegate.replaceAll(/([^ ]+) \(.*/, '$1')
		return delegate.replaceAll(/([^ ]+) \(.*/, '$1')
	} else {
		return delegate
	}
}
assert "nemo_kaz (kazuo nemoto)".getID() == "nemo_kaz"

// 検索単語エンコード
String.metaClass.encodeIt = { ->
	return URLEncoder.encode(delegate,"UTF-8")
}
assert "ツイッター".encodeIt() == "%E3%83%84%E3%82%A4%E3%83%83%E3%82%BF%E3%83%BC"

// main
if (args.length == 0) {println "検索単語を指定してください"; return }
		
Long counter=1
for (;;){
	def feed=null
	def atom2 = ("http://search.twitter.com/search.atom?q="+args[0].encodeIt()).toURL().text
	feed = new XmlSlurper().parseText(atom2)
	feed.entry.collect{it}.reverse().each {
		if (counter < it.id.toString().getNum().toLong()) {
			counter = it.id.toString().getNum().toLong()
			println "■"+it.title +"  "+it.author[0].name.toString().getID() 
			//println it.link[0]
			//println "class="+it.published[0].toString()
		} else {
			Thread.sleep(1000*90)
		}
	}
}

動作イメージ

スピーカーが来ない.... #javaonejp skrb

■[CodeGeneration] @Lazyフィールドにつけると、初めてアクセスするときに初期化するようなアクセサを生成してくれる。 #javaonejp nobeans

■[CodeGeneration] @Lazyで展開される実装はdouble-checked-lockingっぽい。スレッドセーフか?というツッコミに、多分Yes、といってたけど、Java5以降はね、という条件が必要だと思った。 #javaonejp nobeans

■[CodeGeneration]後はアノテーションによるAST変換の例をいくつか紹介してから、DbCGroovy実装であるGContractsの紹介。アノテーションクロージャで事前条件と事後条件を指定すると実行前後でチェックする実装をAST変換で生成。 #javaonejp nobeans

■[CodeGeneration]次は、FindBugsGroovy版的なCodeNarc。発見できるバグの種類は前者が200以上なのに対して、60いくつと少なめだけど、CodeNarcはAST変換でバグチェックを実現してるんだよ、と。 #javaonejp nobeans

■[CodeGeneration]Groovy標準付属のツールで、ASTツリーをGUI表示できる。その構造の見方の説明と、AST変換をするためのASTTransformationの実装の仕方の説明。 #javaonejp nobeans

■[CodeGeneratin]AST変換といっても文法的には万能じゃなくて、Groovyとして正しい文法でなければいけない。文法さえ正しければ、その意味は自由に書き換えられる。文法NGならSyntaxErrorが発生してAST変換まで到達しない。 #javaonejp nobeans

■そろそろModular&Jigsawが始まりそう。 #javaonejp nobeans

■@skrb ですよねー!だからこそ貴重な機会を大事にしたいです。 #javaonejp kawamnv

セッションがはじまるまでウトウトしていた。いつのまにか部屋がいっぱいになっていた。このセッションもffull #javaonejp skrb

2010-08-15 [Groovy] ソースコード同士の類似性評価ツールを作ってみた

Q: あなたはテストエンジニアです、ここにテストしなくてはならないソースが大量にあります。

しかし、よくみるとコピペメソッドによる類似コードが多数あり、ロジックを共有してるコードが大量にあります。従って、全てのコードテストする必要はなさそうです。

そこで、ここで類似コードに関しては、代表的ないくつかをテストするという抽出テストにしたいと思いました、ここで、どうやって選別しますか?


A:類似したコードを群として束ね、類似性の高いコードテストを割愛します。

類似性検出方法は下記の手段を用います。


A B C D のコードがあった時。

ひとつめは

  1. Aのコードを2回足しあわせたものを作ります。 A+A
  2. 次にそれを圧縮します。 zip(A+A)
  3. そして、それをファイルサイズで割った値を算出します。 zip(A+A)/size(A+A)=f(AA)

ふたつめは

  1. AとBのコードを足しあわせたファイルを作ります。 A+B
  2. 次にそれを圧縮します。 zip(A+B)
  3. そして、それをファイルサイズで割った値を算出します。 zip(A+B)/size(A+B)=f(AB)

ここで

f(AB)/f(AA)の値が1に近いとBはAとはあまり違わないものであるといえます。

もしも

f(AB)/f(AA)>1 の場合、1より大きい程、BはAとは異なったものであるといえます。

ここでzip()はrunlength方を使用していると想定しています。

runlength方は、ファイル内で同一パターンを見つけると、前出と同じ、といった表記に置換して圧縮する一般的な圧縮手法です。

動かし方

ソースコードの置いてあるディレクトリーの元の部分でこのスクリプトを動かすと、その下にある

コードの全てに対して、コード間の距離を評価します。

課題

実はすごく遅いです。当たり前、毎回圧縮しているのだから、ファイルIOをもっと減らしてマルチスレッド

しないと実用的にはならない予感がします。

本来テスト対象コードが多すぎるから絞り込みたいという動機があるので、

処理速度がもっと速くないと使えないでしょう。

// ソースコード間の違いを評価するツール
List codes=[]
// ここでは 拡張子がjavaのコードを再帰的に収集します。
new File(".").eachFileRecurse { file -> 
	if(file.isFile() && file.name.endsWith("java")) { 
		name = file.getPath() //+file.getName()
		codes.add(file.getPath())
	}
}
println "検査対象コード"
println codes
println "ソース間距離: (100より大きいほど、二つのファイルは異なっている。"

num = 1
for (x in (0..codes.size-1)) {
	for (y in (0..codes.size-1)) {
		if (1 /* x!=y*/) {
			print "["+num++ +"]"+codes.getAt(y)+" "+codes.getAt(x)+"\t"
			isUnique(codes.getAt(x), codes.getAt(y))
		}
	}		
}

def isUnique(code1, code2) {
	File output0 = new File("doubled.txt")
	output0.write("")
	new File(code1).eachLine { line1 ->
		//println line1
		output0.append(line1)
	}
	new File(code1).eachLine { line1 ->
		//println line1
		output0.append(line1)
	}

	File output = new File("merged.txt")
	output.write("")
	new File(code1).eachLine { line1 ->
		//println line1
		output.append(line1)
	}
	new File(code2).eachLine { line2 ->
		//println line2
		output.append(line2)
	}

	proc = "cmd /c gzip -f doubled.txt".execute()
	proc.waitFor()

	proc = "cmd /c gzip -f merged.txt".execute()
	proc.waitFor()

	def zaa = new File("doubled.txt.gz").size() 
	def zab = new File("merged.txt.gz").size() 
	def a   = new File(code1).size()
	def b   = new File(code2).size()
	println " 類似性 ="+( (zab/(a+b))/(zaa/(a+a)))*100
}

実行イメージは例えば以下のようになります。

抽出方法とか、計算の効率化とか、もう少し改善したいです。

-------------------------------------------------------------------

検査対象コード

[.\a.java, .\b.java, .\SOURCE1\a.java, .\SOURCE1\b.java]

ソース間距離: (100より大きいほど、二つのファイルは異なっている。

[1].\a.java .\a.java 類似性 =99.9551166900

[2].\b.java .\a.java 類似性 =37.2159692800

[3].\SOURCE1\a.java .\a.java 類似性 =192.5814740900

[4].\SOURCE1\b.java .\a.java 類似性 =103.5254833100

[5].\a.java .\b.java 類似性 =152.3449010600

[6].\b.java .\b.java 類似性 =99.9632623700

[7].\SOURCE1\a.java .\b.java 類似性 =178.8919630900

[8].\SOURCE1\b.java .\b.java 類似性 =279.0446589500

[9].\a.java .\SOURCE1\a.java 類似性 =27.5365924800

[10].\b.java .\SOURCE1\a.java 類似性 =6.2432073200

[11].\SOURCE1\a.java .\SOURCE1\a.java 類似性 =97.5609756100

[12].\SOURCE1\b.java .\SOURCE1\a.java 類似性 =12.7184763200

[13].\a.java .\SOURCE1\b.java 類似性 =133.4013067100

[14].\b.java .\SOURCE1\b.java 類似性 =87.9460498600

[15].\SOURCE1\a.java .\SOURCE1\b.java 類似性 =115.114421600

[16].\SOURCE1\b.java .\SOURCE1\b.java 類似性 =99.9902913200

2010-05-22

[][]「並行プログラミング原理から実践まで」5章の補助資料書きました。

 

 

「並行プログラミング原理から実践まで」を社内勉強会で、輪読しています。

今回、第5章を担当しました。

解説資料のすべては下記URLから原板がダウンロードできます。

改変、再配布は自由とのこと。

Index of /acafinal/ACA Self Learn

 

わかりにくい部分に、日本語コメントを追記して使用しました。


このパワーポイントの資料は、本より後から作られたものらしく、本とは構成が違っているので、併読すると、かえって混乱する可能性もあります。

jsr166y forkjoinを理解する前提として、java.util.concurrent をあらためて深掘りして理解しておく必要があると思います。



2010-05-04 [Groovy]ドライブ毎の空き容量を表示する。

小さいけど実用になるGroovyコードメモ

その昔、DOSで動く FREE.COMというツールがありました。

ドライブ事の残量を示してくれました。大きなファイルを書き出したりする前に

最も大きな空きスペースのドライブを確認するときなどに便利でした。

ファイル名は "FREE.COM" などと言う、おいしすぎる名前なので、

もはやネット検索でも、再発見はできそうにない名前ですので、

記憶していたイメージにもとづきGroovy再開発してみました。

Windows専用になります。

(drive in "C".."Z") という拡張for文がちょっと便利ですね。

動作イメージ

drv [  空き ]G [  総計 ]G [Free]%
C:\ [   49.0]G [  110.7]G [44.3]%
D:\ [   16.0]G [   99.8]G [16.1]%
Z:\ [    0.3]G [    0.3]G [100.0]%

ソース

println "drv [  free ]G [ total ]G [free]%"
for (drive in "C".."Z") {
	file = new File("${drive}:/") 
	BigDecimal free = file.getFreeSpace()/100000000
	BigDecimal total= file.getTotalSpace()/100000000
	if (total >0) {
		print file
		BigDecimal vaca = free/total*100
		printf (" [%7.1f]G [%7.1f]G [%2.1f]",free,total,vaca)
		println "%"
	}
}

2010-05-03 [Groovy]URLDecodeされなかったファイル名を直す。

小さいけど実用になるGroovyコードメモ

Firefox pluginの Video DownloadHelperというツールがあります。

これは別に動画ダウンロード専用ではなく、拡張子を追加定義すれば ppt や docpdf も一気に落とすことが出来ます。

ただし日本語対応していないので、各種日本語名のファイルダウンロードした時、ファイル名がURLDecodeされないままでファイルが落ちてきます。

例えば "ファイル名.pdf" というファイルは "%83%74%83%40%83%43%83%8B%96%BC.pdf"

という名前となってしまいます。

充分に日本語化対応していないツールでは、時々あることなので、この名前を元に戻すスクリプトを書きました。

開始ディレクトリーから下のファイル全てに対して、一気にファイル名のURLDecodeの書き戻しします。

new File(".").eachFileRecurse { file -> 
	if(file.isFile()){
		curName = file.getPath().replaceAll(/.\\(.*)/) {m0,m1 -> m1}
		newName = new File(URLDecoder.decode(curName, "UTF-8"))
		println "現行ファイル名: "+curName
		println "新規ファイル名: "+newName
		file.renameTo(newName)
	}
}


2010-04-27 [Groovy]コマンドイラン電卓

小さいけど実用になるコードメモ

Groovyで書いた、コマンドラインでの電卓

eval()がある言語は、どれで書いても、きっとこんな感じになるのではないかと。

import groovy.util.Eval
if (args.length ==0) {
	println """Groovy電卓 使用例: dentaku 1+2*3
第一引数に 計算式を指定してください"""
	return
} 
def eval = new Eval()
println eval.me(args[0])

2010-02-20 bit.lyでの圧縮をWeb APIでなく実行するGroovyスクリプト

tyamaさんの

bit.ly が普通におもしろかったのでGroovyAPIを使って遊んでみた

http://d.hatena.ne.jp/mottsnite/20100209/1265725950

エントリーを見てbit.lyのAPIについて納得。

今まで適当にheaderのスクレイプでbit.ly圧縮していました。

Web APIを探す努力もしていませんでした。

APIがあるなら使うべきなので、そのうちこのメソッドはreplaceします。

ちなみに j.mp は単に bit.ly のエイリアスです。

headerの場合はloginとかなしでの実行となります。

今もこのメソッドでbot動かしています。


def getJmp(String longstr) {
	def url = 'http://bit.ly/?s=&keyword=&url='+URLEncoder.encode(longstr,"UTF-8")
	def ans = ""
	url.toURL().getText("UTF8").eachLine { 
		if (it==~/.*\"shortUrl\".*\"(http.*)\".*/) {
			ans = it.replaceAll(/.*\"(http.*)\".*/) {m0, m1 -> m1 }.replaceAll(/bit\.ly/,"j.mp")
		}
	}
	return ans
}
assert getJmp('http%3A%2F%2Fwww-06.ibm.com%2Fsoftware%2Fjp%2F')== 'http://j.mp/cYbe1'

2009-12-06 Twitter Streaming API でTLをテキストでだらだら出力するGroovy

TwitterのTimeLineの出力をだらだらコンソールに出力するGroovyスクリプトです。

フォロワー数は200以下のアカウントでないと filterが動作しなくなります。

APIの制限です。

http://yusuke.homeip.net/twitter4j/ja/api-support.html#Streaming%20API%20Methods

の birddog filter() あたりの記述に制限も解説されています。

Pagingできるようなので、うまくやるとフォロアー数の制限を超えられるかもしれません。

そこは、まだ調べていません。

@Grab は、ついていますが、Groovyバージョンで書式が変わるので、使わなくても良いと思います。

動作させると、塊ではなく、一件ずつ、だらだら "timestamp+id+本文" の書式でテキストで出力され続けます。



import twitter4j.http.* 
import twitter4j.*

start() 
 
@Grab(group='net.homeip.yusuke', module='twitter4j', version='[2.0.10,)') 
def start() 
{ 
def uid="ユーザーID"
def pwd="パスワード"

	def twitter = new Twitter(uid, pwd ) 
	def userIds = twitter.friendsIDs.IDs 
	
	userIds.each {println " - " + it}
	
	println "Got friends userIds: ${userIds.size()}"
	def twitterStream = new TwitterStream(uid, pwd) 
	twitterStream.statusListener = [  
		onException : { ex -> println ex},  
		onStatus : { status ->
			//status -> println status 
			def time = status.toString().replaceAll(/.*createdAt.* ([0-9][0-9]:[0-9][0-9]:[0-9][0-9]) .*, id=.*/) {m0, m1 -> "${m1}" }
			def name = status.toString().replaceAll(/.*screenName='(.*)', location.*/) {m0, m1 -> "${m1}" }
			def text = status.toString().replaceAll(/.*text='([^']*)', source='.*/) {m0, m1 -> "${m1}" }

			println time+" "+name+"\t"+text
		} 
	] as StatusListener 
	twitterStream.filter(0, userIds, [] as String[]) 
}

2009-08-29 GroovyでTwitter botを作るための code部品

あるTwitterアカウントでの最近の発言群の中心をなすキーワード抽出したリストを作る。

これによりタグクラウドを作る時の部品にする。

または、収集ボットを作る時に、似たような投稿はふるい落とすことに使う。

それまでの投稿内容のキーワードを10単語まで、バッファに保存し続けて

今回収集した投稿文のキーワードが、いまあるバッファにある単語と一致したら、

同一トピックについて語った文面であると判定して、評価を下げます。

これによって、

例えばあるニュースが流れて、それに反応して多くの人がつぶやいたとします。

捕捉ボットは、その場合、一番最初につぶやいた人の文面は普通にキャッチしますが、

番手以降のつぶやきの評価は、一番手の発言で使用された単語とかぶるので、

そのつぶやきの捕捉確率を下げます。

その後もつぶやきを捕捉し続けて、その単語がバッファ辞書から流れて消えていけば、またおなじ捕捉確率に戻ります。

キーワードの除外単語は

 ハッシュタグユーザーID、短縮URL

としました。

Yahoo APIのキーフレーズ抽出APIを使用しました。使用言語はGroovyです。

import twitter4j.*

cache=["某0","某1","某2","某3","某4","某5","某6","某7","某8","某9"]

Twitter twitter = new Twitter("ユーザーID","パスワード");
Iterator <Status> i= twitter.getUserTimeline("誰かターゲットのID").iterator();
	while(i.hasNext()) {
		ans = i.next().getText()
		getKwd(ans)
	}

def getKwd(String text) {
	parm1 = URLEncoder.encode(text.replaceAll(/#[^ ]+/,"").replaceAll(/@[^ ]+/,"") ,"UTF-8") 
	 // ハッシュタグとIDは除外
	def rssFeed =  ("http://jlp.yahooapis.jp/KeyphraseService/V1/extract?appid=取得したYahooAPIのID&sentence="+parm1).toURL().getText("UTF8")
	def rss = new XmlSlurper().parseText(rssFeed)
	kwd0= (rss.Result.Keyphrase[0]).toString().replaceAll(/ /,"")
	kwd1= (rss.Result.Keyphrase[1]).toString().replaceAll(/ /,"")
	if (kwd0 != "bit.ly"&& kwd0 != "tinyurl.com"&& kwd0 != "ff.im") {
		cache.add(kwd0)
		cache.remove(0)
	}
	if (kwd1 != "bit.ly"&& kwd1 != "tinyurl.com"&& kwd1 != "ff.im") {
		cache.add(kwd1)
		cache.remove(0)
	}
	// 短縮URLは除外
	println cache
}

ここではバッファ辞書サイズは10単語、ひとつの文から2単語ずつ抽出しています。

動作イメージ

[某2, 某3, 某4, 某5, 某6, 某7, 某8, 某9, 今多摩川, 花火]
[某3, 某4, 某5, 某6, 某7, 某8, 某9, 今多摩川, 花火, 口語体]
[某5, 某6, 某7, 某8, 某9, 今多摩川, 花火, 口語体, Gaelyk, Groovy]
[某7, 某8, 某9, 今多摩川, 花火, 口語体, Gaelyk, Groovy, JConsole, JRuby]
-- 以下続く --

ときどき対象外の単語があったときは、二つずつひろうとは限らなくなります。

2009-08-01 Google App Engine上でGroovyとTwitterを動かす為のセットアップガイ

Google App Engine上でTwitterGroovyで動かす情報

(bot作ろう会 Groovy分科会は、会員絶賛募集中です。)

必要なファイルは下記zipにまとめてあります。

http://textcode.vs.land.to/GROOVY/TwitterBotGroovy1.zip

まず、Java環境でのHello Worldまでは完了しているものとします。

■ Twitter4j と Groovyjarの配備


以下の二つのjarを、以下の位置に配置します。

war/WEB-INF/lib

groovy-all-1.6.3.jar

twitter4j-1.0.4.jar

のふたつのjarを追加します。ここwar以下のファイルはserverに実際にdeployされます、

これによりこれらのjarサーバにも送られます。

f:id:nemo_kaz:20090801185229p:image


置き場所は、例えば、

c:\workspace\GroovyBotTemplate1\war\WEB-INF\lib  

とかになりまか。

eclipseの該当ディレクトリに直接ファイルを置いて、

プロジェクト右クリック -> Refresh

で見えるようになります。

f:id:nemo_kaz:20090801185230p:image


Groovy ファイル置き場の用意

WEB-INF右クリック->New-Foldergroovyフォルダーを作成します

f:id:nemo_kaz:20090801185231p:image


■Groovletの関連づけ

web.xmlservlet mappingのルールを追加

以下の2定義でワンセットです。

拡張子Groovyファイルは GroovyServletとして名前を共通して与え、そのServletは grovy.servlet.GroovyServlet クラスとして扱いますという意味です。

f:id:nemo_kaz:20090801185232p:image


下記定義部分をご自分web.xmlに追加してください

    <servlet>
		<servlet-name>GroovyServlet</servlet-name>
		<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
		<servlet-name>GroovyServlet</servlet-name>
                <url-pattern>*.groovy</url-pattern>
    </servlet-mapping>

■Groovletの配置

groovyフォルダーの下に Hello.groovyという名の groovlet (Groovy Servlet)を置きます。

html.html {
    head {
        title "Hello"
    }
    body {
        p "Hello from Hello.groovy"
    }
}

ここでプロジェクト動かしてみましょう

f:id:nemo_kaz:20090801192054p:image


■ Hello from Hello.groovy が見えること。

http://localhost:8080/Hello.groovy を指定して Groovletが見えることを確認します。

f:id:nemo_kaz:20090801185233p:image


下記の様なHTMLがGroovletによって作られています。

Groovlet便利でしょ。

<html>
  <head>
    <title>Hello</title>
  </head>
  <body>
    <p>Hello from Hello.groovy</p>
  </body>
</html>

■今度はTwitter bot の骨格を作って、現在時刻をつぶやいてみましょう。


f:id:nemo_kaz:20090801185234p:image

下記コード Jihoubot.groovygroovyフォルダに置きます。これを動かしてみましょう。

import java.text.*
import twitter4j.*

now = new SimpleDateFormat("yyyy/MM/dd HH:MM:SS").format(new Date())

twit = new Twitter("あなたのuserid","あなたのpassword")
twit.update("現在の時刻は ${now} ")

html.html {
    head {
        title "Jioubot"
    }
    body {
        p "posted ${now} "
    }
}


はい、これでご自分Twitterアカウント現在時刻が投稿されたでしょうか。

cookieがセットできないとか、時間が日本時間ではないとか

まだいまいちな部分がありますが、これで投稿までは出来ましたね。

投稿用お試しアカウント coolpoco を見ると、

うまくいった時の実行結果が分かると思います。

http://twitter.com/coolpoco

あと汎用で組み込まなくてはいけないのは

あたりですね。

とりあえず第一回での作業内容としては、このあたりでよいと思います。

Groovyがいい感じだということがおわかりいただけたと思います。

■ BOTTUKU の favicon.ico (もはや公式アイコン?) も入れておきました。

 これはお好みでwarの直下のindex.htmlと同列に配置して使いますが、これはお好みです。

2009-07-21 JavaOne2009の Core Java SEの面白そうな資料のメモ

JavaOne 2009の資料がdownload出来るようになってます。

http://developers.sun.com/learning/javaoneonline/j1online.jsp?track=javase&yr=2009


Core Technology: Java SE and Desktop で、面白そうな資料のリンクメモ

TS-3968.pdf JavaFXGroovy カヌーのDierk Konigが書いている

TS-4215.pdf Groovy1.6 新機能 GAEで動作させる話もあり

TS-4487.pdf Scala入門

TS-4620.pdf 同期処理

TS-4955.pdf GroovyJRubyの比較 104ページ

TS-4961.pdf LL Patterns LLでGoFを書くとどうなるか

TS-5061.pdf Teracottaの分散GC 後で理解する

TS-5217.pdf EffectiveJava2からの抜粋?

TS-5301.pdf Hudson Kawaguchiさんスピーカーだったらしい、唯一の日本人では?

TS-5385.pdf Azul VM クラウド的な意味で、後で理解する

TS-5395.pdf ActorベースScala同期化、なにやら重要そうだが、Scalaの一般理解が先


毎年、全部ダウンロードするが、なかなか呼んでいられない。

2009-06-16 Gr*ワークショップ3で使用した資料

JGGUGワークショップ第三回で

TwitterGroovyからポストする

Google Calendarの今のタイムスタンプにつぶやきを記録する、

Google Calendarライフログ的使い方のサンプルコードを上げました。

http://textcode.vs.land.to/GROOVY/

2009-03-14 ひらがな->カタカナ変換Groovyスクリプト

各種名簿を整理するついでに、読み仮名を統一したかったので

カタカナをひらがなに変換するGroovyスクリプトを書きました。

//  全角ひらがな -> 全角かたかな変換

def String hira2kata(String a) {
	a = a.replaceAll(/あ/,'ア').replaceAll(/い/,'イ').replaceAll(/う/,'ウ').replaceAll(/え/,'エ').replaceAll(/お/,'オ')
	a = a.replaceAll(/ぁ/,'ァ').replaceAll(/ぃ/,'ィ').replaceAll(/ぅ/,'ゥ').replaceAll(/ぇ/,'ェ').replaceAll(/ぉ/,'ォ')
	a = a.replaceAll(/か/,'カ').replaceAll(/き/,'キ').replaceAll(/く/,'ク').replaceAll(/け/,'ケ').replaceAll(/こ/,'コ')
	a = a.replaceAll(/さ/,'サ').replaceAll(/し/,'シ').replaceAll(/す/,'ス').replaceAll(/せ/,'セ').replaceAll(/そ/,'ソ')
	a = a.replaceAll(/た/,'タ').replaceAll(/ち/,'チ').replaceAll(/つ/,'ツ').replaceAll(/て/,'テ').replaceAll(/と/,'ト')
	a = a.replaceAll(/な/,'ナ').replaceAll(/に/,'ニ').replaceAll(/ぬ/,'ヌ').replaceAll(/ね/,'ネ').replaceAll(/の/,'ノ')
	a = a.replaceAll(/は/,'ハ').replaceAll(/ひ/,'ヒ').replaceAll(/ふ/,'フ').replaceAll(/へ/,'ヘ').replaceAll(/ほ/,'ホ')
	a = a.replaceAll(/ま/,'マ').replaceAll(/み/,'ミ').replaceAll(/む/,'ム').replaceAll(/め/,'メ').replaceAll(/も/,'モ')
	a = a.replaceAll(/や/,'ヤ').replaceAll(/ゆ/,'ユ').replaceAll(/よ/,'ヨ').replaceAll(/ら/,'ラ').replaceAll(/り/,'リ')
	a = a.replaceAll(/ゃ/,'ャ').replaceAll(/ゅ/,'ュ').replaceAll(/ょ/,'ョ')
	a = a.replaceAll(/る/,'ル').replaceAll(/れ/,'レ').replaceAll(/ろ/,'ロ').replaceAll(/わ/,'ワ').replaceAll(/を/,'ヲ')
	a = a.replaceAll(/ん/,'ン')
	a = a.replaceAll(/が/,'ガ').replaceAll(/ぎ/,'ギ').replaceAll(/ぐ/,'グ').replaceAll(/げ/,'ゲ').replaceAll(/ご/,'ゴ')
	a = a.replaceAll(/ざ/,'ザ').replaceAll(/じ/,'ジ').replaceAll(/ず/,'ズ').replaceAll(/ぜ/,'ゼ').replaceAll(/ぞ/,'ゾ')
	a = a.replaceAll(/だ/,'ダ').replaceAll(/ぢ/,'ヂ').replaceAll(/づ/,'ヅ').replaceAll(/で/,'デ').replaceAll(/ど/,'ド')
	a = a.replaceAll(/ば/,'バ').replaceAll(/び/,'ビ').replaceAll(/ぶ/,'ブ').replaceAll(/べ/,'ベ').replaceAll(/ぼ/,'ボ')
	a = a.replaceAll(/ぱ/,'パ').replaceAll(/ぴ/,'ピ').replaceAll(/ぷ/,'ブ').replaceAll(/ぺ/,'ペ').replaceAll(/ぽ/,'ポ')
	a = a.replaceAll(/う゛/,'ヴ')
}

//test code
assert hira2kata("あぜるばいじゃん") == "アゼルバイジャン"

元ネタにしたSEDはこちらですが、GroovyよりもSEDの方がすっきり感がありますね。

y/ぁあぃいぅうぇえぉお/ァアィイゥウェエォオ/
y/かきくけこさしすせそたちっつてとなにぬねのはひふ/カキクケコサシスセソタチッツテトナニヌネノハヒフ/
y/へほまみむめもゃやゅゆょよらりるれろわをん/ヘホマミムメモャヤュユョヨラリルレロワヲン/

s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s///g
s/う゛//g

2009-02-14 デブサミ2009に行ってきました。

デブサミ2009に行ってきました。

http://codezine.jp/trackback/devsumi2009/

何かとRubyの陰に隠れがちなGroovyですが、

JGGUG (Japan Grails/Groovy User Group)ジェイガクとして正式発足しました。

勉強会勉強会デブサミ2009吉岡アワーで

山田さんがLTしている様子がUstreamで分かります (01:07:28〜)

http://www.ustream.tv/recorded/1146074

今年のデブサミクラウド系のセッションが多かったですね。

通常のクラウドの話は、ビジネス的な話が多くて食傷気味でしたが

プログラミングの視点でのディスカッションなので、新鮮でした。

2009-01-19 ファイルの添え番号の桁を3桁に揃えるGroovyスクリプト

開始ディレクトリー以下にあるjpgファイルの添え番号の桁を3桁にそろえるGroovyスクリプト

FlashExtrachtフラッシュファイルから画像抽出したりした時には、

フラッシュの中のjpegファイル名か hoge[1].jpg とか hoge[11].jpg とかになって出てくるわけですが、この場合、ソートして見ようと思っても、hoge[1].jpg,hoge[10].jpg,hoge[100].jpg

の様にしか並ばないので、元々の画像の並び順に意味があった場合には、不都合が生じます。

そこでソート可能な様に全ての添え番号を3桁に揃えるGroovyスクリプトを書きました。

例えば

hoge[1].jpg --> hoge[001].jpg

hoge[11].jpg --> hoge[011].jpg

という風にリネームします。

    padLeft()を使ってコード短縮しました

// 開始ディレクトリー以下にあるjpgファイルの添え番号の桁を3桁にそろえる
// 例:hoge[10].jpg --> hoge[010].jpg
new File(".").eachFileRecurse { file -> 
   if(file.isFile() && file.name.endsWith("jpg")) { 
      name = file.getName()
      newname = name
      newname = file.getName().replaceAll(/\d+/){ it.padLeft(3, '0') }
      if (name != newname) {
         println name+" renamed to "+newname
         file.renameTo( new File(file.getParent()+"/${newname}") )
      }
   }
}

fumokmmfumokmm 2009/01/21 00:15 nemo_kazさんはじめまして。

ファイル名の数値が含まれる箇所が一箇所だけなら、
text.replaceAll(/\d+/){ it.padLeft(3, '0') }
のようにすると簡単に3桁に変換できます。

nemo_kaznemo_kaz 2009/01/21 22:01 fumokmmさん、ありがとうございます。
コード、ブラッシュアップしました。

2009-01-18 Groovyなう&ふゅーちゃーに出席しました。

Groovyなう&ふゅーちゃーに出席しました。

Groovy1.6の最新情報です。

私はまだ1.5ユーザーですが、1.6を使いたい理由は、速い、safe reference operatorが使える。

Java7との親和性も当然高まっています。

資料:

http://grails-ja.googlegroups.com/web/GroovyNowAndFuture.ppt

ustream:

http://www.ustream.tv/channel/grailscodereading-16

以下は、出席したときのメモ書き

Groovy 1.6について

エルビス演算子 ?:

三項演算子相当

A?: B とは if(A) {A} else {B}

Java7のは safe reference operator相当 Rubyの場合は .? と書く

ジョイントコンパイ

Class A {

B b;

}

Class B extends A{}

コンパイルできなかった "groovyc -j" で実行可能

JavaScriptの様に、クラスも、インスタンスも動的にメソッド書き換え可能、

 無秩序すぎないか、

  Grailsだったらmetaclassの中でのみ動的な変更可能となっており、整理できる。

Expando Meta Class (EMC)

多重代入

分岐してもreturn省略可能 

AST変換

EMS DSL

実行時Mixed-in

ツールGrape

最初は、Javaの数十倍遅かった、

The Computer Language Bechmarks Game a.k.a "shootout"

Groovyで遅いならそこだけJava化すればよいだけ

ライブラリの性能はJavaと同じ

1.5.6までは遅かったが、1.6からは速い ただし起動は遅くなった

メソッド呼び出しが高速化した JRubyRuby1.9相当の速度

 "CallSite" cache の実装、2回目以降は、呼び出し側が保持する、みつけたmethodを再利用する 

  expandoMetaclassであっても発見容易

 "CallSite-Array"という新規な変数を持ち、探索コストがなくなる

DefaultGroovyMethod#additionals を参照

インライン展開 HotSpot Deoptimization

Grape 依存クラス自動Downloader

Maven/RubyGems みたいなもの Ivyとはモジュール管理に特化したMaven

走行中もDownloadできる

Grape.grab(group:'org.jidesoft',version:':[2.2.9)'))

Javaでもインスタンスのmetaclass変更可能

"xxx".metaClass.a ={print "hello"}

"xxx".a()

AST変換

Groovy.JDBC で現的的に使っていた

.netLINQ もやっていた

Groovyとしてsyntex errorを起こすものは変更できない

@Bindable / @Vetoable = Java.beans.propertyChangeSupport

@Singleton

@Immutable

@Delegate

@Lazy 遅延生成

@Category / @Mixin

@PackageScope

Retention Policy = Source の扱い、多分マクロの位置づけ

String.mixin Date

assert "a".getTime() == xxxxx エポックからの時間が分かる、意味不明になりがち

マルチ代入

def (a,b) =[1,2] <-- def a=1; def b=2 のこと

if(x%2==0) {true} else {false} <-- 2カ所でreturnできる

EMC DSL 一気にメソッドが定義できる String.metaClass.define { ここにメソッドがいっぱ書ける}

 これでメソッドが中途半端に追加された状態が隠せる

Grape の annotation表記は冗長

Javaアノテーションは methodとclassのみ

MOPのリフレッシュ予定あり NG言語のコアが役に立つ

2008-12-04 Groovy Clousureは、Methodではないので全ての処理が終わらないと終

Groovy Clousureは、Methodではないので全ての処理が終わらないと終了しない件

GCRGroovy勉強会に行ってきました。

今回特にためになったのは、Closureの挙動について、その終了の仕方がMethodとは異なること。

つまりClosureはMethodsではないので、もらった入力は全て処理する。

 [1,2,3].each {print it; return } この出力は"123" 全て処理してから終わる

 for (it in [1,2,3]) {print it; return}   この出力は"1" ひとつの出力で終わる

もう一つ確認

1.upto(3) { print it ; if (it>1) return} この出力は"123" 全て終わってからreturnする。


returnを処理の途中で発生させても、println it の部分の処理は10まで進みます。

2008-11-26 第16回オープンソーステクノロジー勉強会に行ってきました。

MapReduceの話を伺いにGREE Labsにお邪魔してきました

以下メモ書き

Preferred Infrastructure 太田一樹さん http://kzk9.net/ http://preferred.jp/

Sedue 分散検索エンジン

Hadoop + EC2 の分散検索

SOSP学会

200億ページ 20kb = 400TB がインターネットの全体 読み込みは100日 400GBが1000台あれば良い

プロセス起動 プロセス監視 デバッグ 最適化 

MPI = Massage Passing Interface が並列プログラミングライブラリ 

HPCはチェックポイントを持って、同期点を確保する

Framework側で持つ

1jobあたり5プロセスが死ぬ

用途

Grep

Sort

Log analysis

Web Graph generation

Machine Learning

Inverted index Construction

Machine Learning

 K-means

Apache ツール出てきた

hadoop Distributed File System

HDFS = Master/Slave Architecture

64MB単位に分割 

 Namenode + Datanode (NamenodeはentryでSPOF)

Master = Jobtracker 事業のタスク分割 全てのTracktrackerへ定期pingを打つ

Slave = Tasktracker

Hadoop streaming は 多言語interface : Rubyからでも呼べる 

Yahoo japan は 2000ノードまでしよう

SIGIR(IR学会)

コミッターのほとんどはYahooFacebook

はてぶもHadoop

FacebookhiveというHadoopラッパーを作った

GFSはAppendできるがHadoopはまだできていない

Hadoopでもlog rotation みたいな仕掛けは使える。

読み込み元のデータとの同期は、できない Latencyは、発生しうる

Javaのthread にはHadoopは勝てない、tasktrackerのlaunchとか、相当overheadがかかる。

大倉努さん http://ohkura.com  blogeye

 Hadoop + EC2

 著者推定

 データマイニングアルゴリズム

 1000万blogのうち500万ブログ

 300GBのデータマイニング

 EC2 = 10cent/hour 1時間10円

 Hadoopは後からnode追加、削除可能 障害マシンの除去可能

 S3 + mySQL使用

 クローラーは落ちやすい

 MySQLデータを置いて重複検知 Hadoopは小さいファイルが苦手

 Index = MySQL + Senna

著者属性推定ジョブ

記事の合体

MappertがReducerに送るとき、途中で共有ファイルシステム上に置かれて、そのファイル名が渡される。

ReducerはMasterに聞いて必要なデータが揃っていたらHTTpで取りに行く

機械学習の最初の入力データは何?

ヤスタケさん

300GくらいならS3でなくEC2で間に合うかも LOCALのデータは EC2の上のデータは消える

アマゾンに1年で40万くらい払った

CRAWLのジョブはつまらない 2〜3台で間に合う

EC2の仮想マシンは、大中小とあるがどれか、1年前は1種類しかない dual coreはあまりメリットない

一台のマシンにMapperとReducerと両方入れて置いた方が良い、同じマシン内部での処理は有利

Hadoopの駄目な点、あまり再起動はない、MasterでCrawlしていたから

優先度設定が最近可能になった data lost はない。

Hadoopじゃなくては駄目な理由は?

計算力のニーズの変動が大きいのでAmazonを使った

2008-08-31 ”ProjectZeroでPHPパート2” PHP勉強会で発表

PHP勉強会第35回で "ProjectZeroでPHPパート2" 発表してきました。

P8ランタイムとは

  • JavaVMで動くPHPJavaの性能が活用できる
  • Javaのメソッドが直接呼べる

などです。

http://docs.google.com/Presentation?id=dc9bnsx3_691g3pcnpcs

2008-08-11 Grovyコンファレンスのスピーカーの方々(一部)

Groovyコンファレンススピーカーの方々のリンク集

キムゾー氏

http://d.hatena.ne.jp/kimzo/comment?date=20080717&section=1216312904#c :title=http://d.hatena.ne.jp/kimzo/comment?date=20080717&section=1216312904#c

]

nobusue氏

http://d.hatena.ne.jp/nobusue/20080717

uehaj氏

http://d.hatena.ne.jp/uehaj/

山田正樹氏 (今回は進行とかで参加)

http://www.metabolics.co.jp/mmw/

るいも氏

http://www.ruimo.com/

竹嵜 伸一郎氏

http://reflex.sourceforge.jp/index.html

今回は、私は発表しません、Guestの方優先にしています。

けっこう懇親会重要かもしれません、Groovy界の交流の場になると思います。

2008-08-03 seasarcon 2008 Autumn でLTします


http://event.seasarfoundation.org/sc2008autumn/

seasarcon 2008 で LT します。

Java + 軽量言語というテーマ

エンタープライズにとっての軽量言語の選択基準という話で

なるべくニュートラルになるようにしつつも、

Groovyの話をします。

2008-07-30 どう書く? org の2次元ランダムウォークの課題回答

どう書く? orgの課題回答です。Groovyを使用しています。

f:id:nemo_kaz:20080730230437g:image

2次元ランダムウォーク

課題の回答です。どう書く? orgには画像が投稿できないので、画面イメージはこちらに置きます。

コードはこちら。


import groovy.swing.SwingBuilder
import java.awt.Color
import java.awt.BorderLayout as BL
import javax.swing.WindowConstants as WC
import javax.swing.BorderFactory as BF
import javax.swing.JOptionPane
swing = new SwingBuilder()
paint = swing.action(
	name: 'Run',
	closure: this.&paintGraph,
	mnemonic: 'R',
	accelerator: 'ctrl R'
)
about = swing.action(
	name: 'About',
	closure: this.&showAbout,
	mnemonic: 'A',
	accelerator: 'F1'
)
frame = swing.frame(title:'2次元ランダムウォーク',
location:[100,100], size:[300,300],
defaultCloseOperation:WC.EXIT_ON_CLOSE) {
	menuBar (){
		menu(mnemonic:'A','Action'){
		menuItem(action:paint)
		}
		glue()
		menu(mnemonic:'H','Help'){
			menuItem(action:about)
		}
	}
	panel (border:BF.createEmptyBorder(6,6,6,6)) {
		borderLayout()
	
		vbox(constraints: BL.CENTER,border:BF.createTitledBorder('Runボタンを押すたびに100回動きます')) {
			panel(id:'canvas')
		}

		hbox (constraints: BL.SOUTH){
			hstrut(width:10)
			button(action:paint)
		}
	}
}

frame.show()

def labeledSpinner(label, value){
	swing.label(label)
	swing.hstrut()
	swing.spinner(id:label, stateChanged:this.&paintGraph,
	model:swing.spinnerNumberModel(value:value))
}
	gfx = swing.canvas.graphics
	gfx.color = new Color(255, 255, 150)
	gfx.color = Color.red
	xpos = 100
	ypos = 100
def paintGraph(event) {

	int width = swing.canvas.size.width
	int height = swing.canvas.size.height
	
	1.upto(100) {
		xdir = Math.random()
		ydir = Math.random()
		if (xdir <0.3333 &&  xpos >5)         { xpos-=5 }
		if (xdir >0.6666 && (xpos < width-5)) { xpos+=5 }
		if (ydir <0.3333 &&  ypos >5)         { ypos-=5 }
		if (ydir >0.6666 && (ypos <height-5)) { ypos+=5 }
		gfx.fillRect(xpos,ypos,4,4)
	}
}
void showAbout(event) {
	JOptionPane.showMessageDialog(frame,
	'''2次元ランダムウォーク
赤い四角がランダムに歩きます。''')
}

2008-07-27 「Java並行処理プログラミング」最終回

Java読書会の「Java並行処理プログラミング最終回でした。

最終回Hackathon的にIPV6での接続テストを実施しました。

Windows XPで実施する場合、以下のコマンドが事前に必要です。

私はWindows XP + Wireless で接続しました。

> netsh interface ipv6 set privacy disabled persistent

> ipv6 -p gpu UseTemporaryaddresses

コードJava読書会の方にポストしています。

f:id:nemo_kaz:20080726151144j:image

2008-06-29 ProjectZeroでPHP



ProjectZeroでPHP という話を第34回PHP勉強会でLightning Talkしました。

http://events.php.gr.jp/event.php/event_show/46

発表10分 

ProjectZeroでPHPを始めるまでの話。

Presentation 

Google Docsプレゼンテーション「ProjectZeroでPHP

http://docs.google.com/EmbedSlideshow?docid=dc9bnsx3_6009k22c5cd



Video

UStream映像

http://www.ustream.tv/flash/video/519509

ちょっと補足

Groovy in Action の和訳がもうじき出ます。

Groovy in Action

Groovy in Action

バイブル的な本なので、これ一冊で足りると思います。

ProjectZeroのアプリケーション記述言語GroovyPHPの2種類です

という二択になります。


Groovyが、なぜブレイクしそうなのかは

http://www.c-sq.com/modules/article/article133.html

のFloyd Marinescu氏の資料を参照。

あたりが理由です。

2008-06-25 ケータイから更新してみる

大阪のカプセルホテルは色々小道具があって面白かった

2008-06-24 テキストマイニングのセミナーがあります。

さりげなく、書いてしまいますが、

7月11日に、テキストマイニングに関するナイトセミナーがあります。 (3人称的に書いていますが、中の人です)

Information Retrieval に関心のある人には良いかも。

「可能性を拡げるテキストマイニング 〜適用事例から先端研究動向まで〜」

http://www.ibm.com/developerworks/jp/evangelist/events/080711.html

解説文が高尚で分かりにくいかもしれませんが、炎上探知機の技術解説と言えば分かりやすいかもしれません。

日本語の構文から意味解釈して、コメント自体が全体でPositiveかNegativeか判定するという

評判分析の話です。 炎上学に興味のある人などに向くかもしれません。

入力フォームの書式が形式的で堅く、エントリーしてもAutoResponseのメールも来ませんが、

特に制限なく、どなたでもエントリー可能です。

ついでにその1週間前の

7月4日SOA実装設計 〜SOAインフラの下流の設計方法論〜」

は、WS-ReliableMessagingの話があります (こっちは中の中の人)

RESTfulなメッセージングの設計をする際に必要な、メッセージの再送信の部分の考え方をまとめます。

2008-06-20 RESTful読書会第3回に出席しました

RESTful読書会第3回に出席しました。

RESTful Webサービス

RESTful Webサービス

30分ほどいただいて、ProjectZeroの話をしました。

動画はこちら、うしろが切れているっぽいです。id:i_ogiさん、ありがとうございました。

UStream

その時使用した資料はこちらです。

ProjectZeroとわたし