Use variables for input and output PyAIML

I have included the below source which is my full project at the moment. What I have working so far is a terminal interface where I input a phrase and it then takes the response (from the AIML database), takes each letter and one-by-one plays the .mp3 sound for that letter to make a BASIC translator (R2D2 here). There are a couple of problems. The first is that it works fine for the first time I enter in a phrase (in that it translates the output perfectly), but then encounters an Index error and the terminal closes. (see figure 1) I don't know what is wrong with it, but suspect it may be something faulty with my while loop.

The other issue I have is that I plan to use this with a speech interface, so I say something, it's run through a STT engine which then outputs what I said as a string. I want that string to then be given as the input to PyAIML to then get a response from and translate it as it does in this program. The problem I have is how to make a variable which can then be used as input to PyAIML. Any ideas how I'd do this?

import aiml
import os
import time

def translate():
    if char == 'a':
        os.system("start a.mp3")
    elif char == 'b':
        os.system("start b.mp3")
    #This continues for all the letters of the alphabet - you get the idea
    else:
        time.sleep(0.1),


k = aiml.Kernel()
k.learn("std-startup.xml")
k.respond("load aiml b")
while True: 
    string = k.respond(raw_input("> "))
    input = string.lower()
    numChar = len(input)
    n = 0
    m = 0
    char = input[n]
    while m < numChar:
        translate()
        time.sleep(0.25),
        n = n + 1
        char = input[n]
        m = m + 1

Note: the response does work; it comes up with this error after the output has been translated.

Answers


Your code is stepping through each character individually, when you should just step through the string (and it will return back each character).

Python is a bit different in that traditional "find the length, set a counter to 0, until count is less than the length, fetch by the counter" pattern is not required.

You can also optimize your code a bit:

import aiml
import os
import time

character_mappings = {'a': 'a.mp3', 'b': 'b.mp3'}

def speak(char):
    out = character_mappings.get(char)
    if out:
         os.system('start {}'.format(out))
    else:
         time.sleep(0.1)

k = aiml.Kernel()
k.learn("std-startup.xml")
k.respond("load aiml b")
while True: 
    text = k.respond(raw_input("> ")) # "string" is a built-in
    for char in text.lower():
        speak(char) # translate is also a built-in
        time.sleep(0.25)

Check n before char = input[n] because n is bigger then length of input

--

Or change

n = n + 1
char = input[n]

into

char = input[n]
n = n + 1

EDIT:

I don't know what you try to do but this

numChar = len(input)
n = 0
m = 0
char = input[n]
while m < numChar:
    translate()
    time.sleep(0.25),
    n = n + 1
    char = input[n]
    m = m + 1

can be done this way

for char in input:
    translate()
    time.sleep(0.25)

but I would do this

def translate(letter):
    if letter == 'a':
        os.system("start a.mp3")
    if letter == 'b':
        os.system("start b.mp3")
    # rest of code
    else:
        time.sleep(0.1)

for char in input:
    translate(char)
    time.sleep(0.25)

or even this

def translate(letter):
    if letter in 'abcde': # all accepted letters
        os.system("start "+letter+".mp3")
    else:
        time.sleep(0.1)

Need Your Help

Installing in Program Files vs. Appdata

windows installer installation

What are the benefits and downsides of installing an application in the user's AppData directory?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.