辞書を片手に~PatternResponderの作成(10) | Pythonでなんか作ってみる

辞書を片手に~PatternResponderの作成(10)

操作ミスで、書きかけが消えてしまいました。

気力も尽きたが、TDDの過程は二度と復旧できないので、概要だけ記述します。


「1つのパターンに対して応答例は「|」で区切って複数設定でき、いずれかがランダムに選択される」を実施しようとしたが、現状では応答例は一つしか保持できない。

そこで、応答例を複数保持するオブジェクトとしてRandomResponderを使うことを思いつく。

まずは、RandomResponderを無理やり利用するために、RandomReponderのnameフィールドを応答例の保持フィールドとして使用した。

次に、RandomRespondeを利用しやすいように「RandomResponderのコンストラクタでファイル名(String)でなくファイル(Reader)を受け取るようにする」を実施する。

しかし、それよりも「応答例の配列(String[])をコンストラクタで受け取れる」方が利用しやすいことに気づき、そのコンストラクタを追加する。

RandomResponderのコンストラクタがごちゃごちゃになっているが、あとでなおすことにして実装完了。


最終的に次のようになった。


public class RandomResponder extends Responder {

String [] resps;
Random rnd;
public RandomResponder(String name) {
this(name,"random.txt",new Random());
}
public RandomResponder(String name,Random rnd) {
this(name,"random.txt",rnd);
}
public RandomResponder(String name,String fileName) {
this(name,fileName,new Random());
}
public RandomResponder(String name,String fileName,Random rnd) {
super(name);
try {
initialize(new FileReader("dics/"+fileName),rnd);
} catch (FileNotFoundException e) {
initialize(new StringReader("\n"),rnd);
}
}
public RandomResponder(String name,Reader reader,Random rnd) {
super(name);
initialize(reader,rnd);
}
public RandomResponder(String name,String[] responses) {
this(name,responses,new Random());
}
public RandomResponder(String name,String[] responses,Random rnd) {
super(name);
this.rnd = rnd;
resps = responses;
}

private void initialize(Reader reader,Random rnd) {
this.rnd = rnd;
resps = loadDictionary(reader);
}
/* (non-Javadoc)
* @see proto.Responder#response(java.lang.String)
*/
public String response(String msg) {
return resps[rnd.nextInt(resps.length)];
}
}

public class PatternResponder extends Responder {

private Pattern[] patterns;
private RandomResponder[] responses;
private Responder randomResponder;

public PatternResponder(String name, Reader reader) {
this(name,reader,new Random());
}
public PatternResponder(String name, Reader reader,Random rnd) {
super(name);
randomResponder = new RandomResponder(name,rnd);

String[] loadStrings = loadDictionary(reader);

patterns = new Pattern[loadStrings.length];
responses = new RandomResponder[loadStrings.length];

for (int index=0;index < loadStrings.length; index++) {
String[] patternAndResponses=loadStrings[index].split("\t");
patterns[index] = Pattern.compile(patternAndResponses[0]);
if (patternAndResponses.length > 1) {
responses[index] = new RandomResponder(name,patternAndResponses[1].split("
\\|"),rnd );
}else{
responses[index] = new RandomResponder(name,new String[]{""},rnd);
}
}
}
public String response(String msg) {
for (int index=0;index < patterns.length; index++) {
Matcher m = patterns[index].matcher(msg);
if (m.find()) {
return responses[index].response(msg);
}
}
return randomResponder.response(msg);
}

public Pattern[] loadDictionaryPattern() {
return patterns;
}

public RandomResponder[] loadDictionaryResponse() {
return responses;
}

}

public class PatternResponderTest extends ResponderTest {

.....

public void testLoadDictionaryResponse() throws FileNotFoundException {
PatternResponder responder = new PatternResponder("pattern",
new FileReader("dics/pattern.txt"));

assertEquals(new RandomResponder[] {
new RandomResponder("", new String[] { "さむくないよ" ,"そうだね"}),
new RandomResponder("", new String[] { "食べれば" }),
new RandomResponder("", new String[] { "いいね" }) }, responder
.loadDictionaryResponse());
}

public void testLoadDictionaryResponseIlliegal()
throws FileNotFoundException {
PatternResponder responder = new PatternResponder("pattern",
new FileReader("dics/random.txt"));

assertEquals(new RandomResponder[] {
new RandomResponder("", new String[] { "" }),
new RandomResponder("", new String[] { "" }),
new RandomResponder("", new String[] { "" }) }, responder
.loadDictionaryResponse());
}

public void testLoadDictionaryResponseIlliegal2()
throws FileNotFoundException {
PatternResponder responder = new PatternResponder("pattern",
new StringReader("test1\ttest1\ntest2\t\ntest3\ttest3"));

assertEquals(new RandomResponder[] {
new RandomResponder("", new String[] { "test1" }),
new RandomResponder("", new String[] { "" }),
new RandomResponder("", new String[] { "test3" }) }, responder
.loadDictionaryResponse());
}

public void testResponse() throws FileNotFoundException {
PatternResponder resp = new PatternResponder("pattern", new FileReader(
"dics/pattern.txt"), new FakeRandomInt());
assertEquals("さむくないよ", resp.response("今日はさむいね"));
assertEquals("pattern", resp.name());
}

......

public void assertEquals(RandomResponder[] expected,
RandomResponder[] actual) {
for (int i = 0; i < Math.min(actual.length, expected.length); i++) {
assertEquals(expected[i].resps, actual[i].resps);
}
assertEquals(expected.length, actual.length);
}
}


ToDoリスト

・正規表現を使ってパターンに反応するResponder(以下の仕様を満たす)

・1つのパターンに対して応答例は「|」で区切って複数設定でき、いずれかがランダムに選択される

・応答例の中に「%match」という文字列があれば、パターンにマッチした文字列と置き換えられる

・RandomResponderのコンストラクタでファイル名(String)でなくファイル(Reader)を受け取るようにする

・RandomResponderのコンストラクタを整理する