Thursday, November 1, 2012

Build a chat bot with ALMOST no "code"

In this post I will introduce you to PyAIML which is an AIML interpreter coded in pure Python. What I mean about almost no code here is that, starting a bot with PyAIML requires very little code in a python script file. Though, you might write a lot for the dialogues !

What is AIML ?

AIML is an XML dialect used to interact with a bot. The most popular example of a bot who understands that dialect is A.L.I.C.E. (Artificial Linguistic Internet Conputer Entity) developped by Dr. Richard Wallace.

You will need:

  • Python 2.7
  • PyAIML (Install instruction will follow);
  • Good dialogue writing skills :).
Installation

For Windows users, just download the latest version of PyAIML from the official website. Save it on your hard drive and install it.

For Linux users, I only know Arch Linux and I know you can find it in the AUR.


The code

Building a chatbot with PyAIML requires minimally two files:
  • A .py file to start the interpreter and make it learn replies;
  • A .aiml file that describes what the bot can reply to what.
Here is a simple example of a bot who recognizes simple greetings and bye's.

.py file:

.aiml file:
In the python code, I simply instantiate a new Kernel object form the aiml library that represents my bot. I then set up a few predicates or what the bot knows which in this case is its own name (Pedro) and the name of its master (Me !). Then I tell the bot to learn the content of the .aiml file I give him (you can tell your bot to learn more than one file) and I infinitely loop responding to any user input.

As for the AIML file, I will not go through every lines or tags but I will tell you about the very basic of the idea. If you never read/wrote XML files in your life, it is not hard and I recommend W3School's Tutorial

  • An AIML file must begin with the aiml root element. The version property is optional;
  • A category element is every known exchange of words between you and the bot;
  • pattern element is one of the user's possible input. Punctuation is ignored. Always uppercase;
  • A that element refers to what the bot already said and puts a context to the conversation;
  • A template element is what the bot will reply. You can have random responses from a given list;
  • A srai element means it redirects to another pattern element;
  • <bot name="something" /> refers to one of the predicates the bot knows;
  • You can use wildcards such as *. Note: a * has less priority than a precise word;
  • You can refer to what was written as * with the element <star index="n"/>
The only thing that I did not cover here is the topic element and everything that goes with it. That elements puts a subject on the conversation !

Here is what a conversation looks like with Pedro:


Loading basic.aiml... done (0.03 seconds)
> Hello !
Buon Giorno !
>  What's your name ?
My creator called me Pedro. What about you ?
> My name is Nylo !
Nice to meet you Nylo
> Bye !
Talk to you next time then even if I might not remember

Wednesday, November 16, 2011

Unit Tests: Part Deux

Oh well, it's been a while, I know... sorry for that.


Like promised this post here is going to check show how to implement unit tests.


I created a simple project with 2 classes, one of them is implementing an interface. Why interfaces ? Because we are going to use what is called mocking, which will ensure that you will indeed test each units of your code and not many at the same time (which is called an integration test). It is the simplest scenario possible, but understanding it will help you a lot as a programmer.


The Setup
I used Visual Studio 2010 as my IDE. Since I'm using .NET 4, my test framework is NUnit (http://www.nunit.org/) and my mock library is Moq (http://code.google.com/p/moq/). Download these two tools and install them (or extract them somewhere you will find afterward). When you create your test project, link these two libraries to the project (and don't forget to link the project(s) you want to unit test.


The code !!
The project structure is simple:
  • IPingTool: An interface with only one method, void Ping();
  • PingTool: A concrete implementation of the IPingToolInterface
  • Server: A simple class that represents a monitored server.


The definition for IPingTool is simple:



And its concrete implementation is as simple:

Now, how do we test it ? Here is a simple guideline: You can test many "success" at the same time, but only one failure at a time. In our case, it's easy, it either works or not. That gives us two test cases:

Voilà ! You have unit tested a class using NUnit. Now, how about some quick explanations ? 

  • The [TestFixture] attribute tells NUnit that this class is a Test class.
  • Each method with a [Test] attribute is... a test ! 
  • Assertions are used to check your values, A LOT of methods are available for you
  • See that [ExpectedException] attribute, it speaks for itself, because sometimes, you do want to throw an exception

Now.. for the other class. The server class is simple:


Let's say this class is your monitored server and every now and then you send a reset command if your server is unreachable. Now.. the testing phase. If anyone thought that to test the class you have to use a PingTool is heading for the wrong way ! Read the code below and you will get the trick:



Yup, instead of using a real PingTool, we fool the Server object by giving him an object we can absolutely control and he won't notice ! This is what I meant by unit testing, we are now sure that each classes is tested separately. A mock object can be setup with a lambda to manage the behavior of each functions (and methods).


That's it folks ! Have fun unit testing.

Tuesday, June 21, 2011

Unit Tests: How and Why ?

Back in college, we were introduced to unit tests only because our teacher HAD TO and not because he felt it was useful. That's what I felt back then. I remember that he even asked me how could he teach that subject to future students to keep their attention after I told him I wrote batches and batches of tests during my internship.

Unit testing is indeed a tedious task and most programmers, or at least new programmers, don't see the potential in writing tests. Again, back in college, we only wrote them to have a grade, so I guess you have to experience it on the field to understand why it is so important. Though, once you decide to write your test cases, another difficulty shows up: are your tests good enough to prove what you wanted to prove ? In my opinion, experience will answer that.

I will still give my opinion about unit tests and talk about why and how you should write them.

The way I see unit tests is simple: imagine an assemblage of pieces, perhaps a car. Sure the car you buy, new or used, is fully functional, but how can we assert that it is okay and safe to drive this vehicle ? I'm not a mechanic, of course, my first reflex is to be sure that all single parts are in good condition: the engine, the transmission, the carburetor, etc. Like I said, I'm not a mechanic. What I'm trying to say is this: if you aren't sure that every single part of your assemblage works properly
, how can you be sure everything will be fine ? That's what you should have in mind when developing a software. In that situation, the parts are your classes. Now, if you are developing a little helper to ease a daily task or any redundant process at your job or things that falls in the category of helping you, unit tests are not necessary in my opinion. I mostly write them for projects of a certain size.. business or personal.

Here's another example, if I already convinced you, you may skip to the code unless you want to hear my little story. Imagine a guitar, an electric one. Can I really say that my guitar is in good condition if I got fret buzz on specific frets ? If one of my pickup has static noise ? Or if my jack outputs low sound ? No, huh? That's what I thought.

Now a software is the same thing, you want everything to work properly. Mostly because object oriented programming encourages you to reuse code. It also helps you designing your system if you decide to go for test driven development, which is basically writing your test cases before or at the same time as your code (but still before writing your actual code). All this will be clear soon =).

Next post will have code !!