rainman rainman - 4 months ago 24
HTML Question

chatbot programming using CGI

I am programming a chatbot using CGI, i have an xml file with the patterns and possible answers, i parse it and store the pattern with its answers in a hash.
i made an interface using HTML, i get the string introduced in an input textfield, and i check if it contains one of the patterns i have in my hash, if yes it prints one of the possibles answers in a textarea(html) what it does not do, i don't know why .

what i want to have is something like this: http://nlp-addiction.com/chatbot/eliza/

here is a part of the xml file:

<?xml version="1.0"?>
<aiml version="1.0">
<category>
<pattern>SARA</pattern>
<template>
<random>
<li>¿Si?</li>
<li>Dime.</li>
<li>¿Qué deseas?</li>
</random>
</template>
</category>
<category>
<pattern>ACTOR</pattern>
<template>
<random>
<li>Mi actor favorito es Arnold Schwarzenegger en "Terminator".</li>
<li>Mi actor favorito es Rutger Hauer en "Blade Runner".</li>
<li>Mi actor favorito es Robin Williams en "El Hombre Bicentenario".</li>
<li>Mi actor favorito es Peter Weller en "Robocop".</li>
<li>Mi actor favorito es Jude Law en "AI".</li>
</random>
</template>
</category>
<category>
<pattern>ACTRIZ</pattern>
<template>
<random>
<li>Mi actriz favorita es Daryl Hannah en "Blade Runner".</li>
<li>Mi actriz favorita es Kristanna Loken en "Terminator 3".</li>
<li>Mi actriz favorita es Persis Khambatta en "Star Trek".</li>
</random>
</template>
</category>
<category>
<pattern>ADAM</pattern>
<template>
<random>
<li>Adam es mi programador. En este momento está muy ocupado.</li>
<li>Adam es mi botmaster. Le daré saludos de tu parte.</li>
</random>
</template>
</category>
<category>
<pattern>ADIOS</pattern>
<template>
<random>
<li>Hasta luego.</li>
<li>Espero haber sido de ayuda.</li>
<li>Espero verte de nuevo.</li>
</random>
</template>
</category>
<category>
<pattern>AFICIONES</pattern>
<template>
<random>
<li>Me gusta ayudar a la gente.</li>
<li>Me gusta conversar con la gente en Internet.</li>
<li>Me encanta visitar zonas turísticas en <bot name="ciudad"/>.</li>
</random>
</template>
</category>
<category>
<pattern>AHORA</pattern>
<template>
<random>
<li>En este momento estoy hablando contigo.</li>
<li>Ahora estoy hablando contigo.</li>
</random>
</template>
</category>
</aiml>


and here is my program:

#!/usr/bin/perl -w

use strict;
use CGI;
use warnings;
use XML::LibXML;
use utf8;

print "Content-Type:text/html\n\n";

binmode(STDOUT,":utf8");
binmode(STDIN,":utf8");

my $query = new CGI;


my $parser = XML::LibXML->new();
my $xmlfile = $parser->parse_file('sara.xml');

my %words;

my @answers;

$xmlfile = $xmlfile->getDocumentElement();



my @kids = $xmlfile->findnodes('//category');

foreach my $child (@kids) {

my $pattern = $child->findvalue('pattern');
@answers = $child->findnodes('template/random/li');

for my $answer(@answers){

push @{$words{$pattern}}, $answer->textContent;
}

}

my $input;
my $reply;

if($query->param('input1')) {
$input = ($query->param('input1') || "");
}

while($query->param('input')) {

foreach my $pattern(keys %words){
if(index(uc $input, $pattern) != -1){

@answers = @{words{$pattern}};
my $n = int rand($#answers + 1);

$reply = $answers[$n];
last;
}
}


}

print <<PAGE;
<html>
<head>
<title>Chat with Sara</title>
<style type="text/css">
input[type=text]{
height:30px;

}

input[type=submit]{
height:30px;
width:65px;
}
</style>
<h1>Chat With Sara</h1>
<form name="e_form" action="http://localhost/cgi-bin/chatbot.cgi" method="post">
<textarea name="e_diaplay" cols="58" rows="20">$reply</textarea>
<br/>
<input type="text" name=\"input1\" size="50">
<input type="submit" name="chat" value="Chat">
</head>
</html>
PAGE


Any hekp ?

Answer

Maybe you have a typo in the while, you are using input instead of input1

while($query->param('input')) {

You could add something to $reply to see it is displayed at all:

You should use foreach instead of while and you could use grep:

my $from_sara;
foreach my $input ($query->param('input1')){
  foreach my $pattern (grep {/^\s*$input\s*$/is} keys %words){
     @answers = @{$words{$pattern}};
     $from_sara = $answers[int rand($#answers + 1)];
     last;
  }
  last if $from_sara;
}
my $reply = "Answer from Sara:\n$from_sara\n";
Comments