Montana Tech of The University of Montana
Computer Science & Software Engineering

CSCI 135
Fundamentals of Computer Science I
Fall 2011



ASSIGNMENT #7

In this assignment, you will be building a program that stores and searches a dictionary of words. The program also speaks words using a library of recorded WAV files (for most of the 5K words anyway). You will gain practice building a common class design pattern in which one class holds a collection of other objects.

Speaking Dictionary

Program input. The program reads in its data using StdIn.java. Here a portion of the dict5k.txt file:
him      5.60991E-04  word_audio/him.wav
across	 5.59660E-04  word_audio/across.wav
died	 5.58570E-04	
often	 5.58313E-04  word_audio/often.wav
problem	 5.58185E-04  word_audio/problem.wav
that's	 5.58137E-04  word_audio/that_s.wav
The first column is the word. The second column is the probability of the word under a language model trained on a large corpus of English. The third column on a line is optional, when present it contains the directory and filename of the audio for the word.

Speaking matching words . Here is the output for a sample run:
% java SpeakText it w.. t.e .est of ti.+ < dict5k.txt
Read in 5000 dictionary entries.
it     it       0.00255839      word_audio/it.wav
w..    was      0.00676185      word_audio/was.wav
t.e    the      0.00534691      word_audio/the.wav
.est   test     3.81697E-4      word_audio/test.wav
of     of       0.00647559      word_audio/of.wav
ti.+   time     7.04731E-4      word_audio/time.wav
The program first reads in the data in the dictionary and outputs the total number of entries. It goes through each command line argument, returning the word that matches the pattern and has the high probability. The program prints one line of output per command line argument. Each output line has four columns: When each line of output is printed, if there is an audio file available, it should play the file. The program should wait for the audio to complete before going on to the next line. The dictionary lookup should be case insensitive (i.e. searching for "the", "The", or "THE" should all return the same thing).

Babble mode If no command line arguments are given, the dictionary goes into "babble mode". It draws a word at random, prints the word, and speaks the word (if an audio file is available). This repeats forever. The words should be drawn uniformly according to the probabilities of the dictionary entries. That is, you should be more likely to draw common words such as "and" and "is" instead of uncommon words such as "sanctions" and "manufactured". Note: you cannot do this by simply choosing one of the 5000 words at random (see the questions section below).
% java SpeakText < dict5k.txt
Read in 5000 dictionary entries.
deal
religion
can
delivered
wouldn't
lot
...
Classes and APIs. You should start by downloading the file speakdict.zip. This file contains recorded audio files for almost four thousand words, so it is a bit big! Unzip the file into the directory you plan to develop your Java programs in. This time, you only get bare bone versions of the three classes you will be developing: Here is the API you should implement in Dict.java:
public class Dict
------------------------------------------------------------------------------------------------------------------------------
public int    size()                                          // how many dictionary entries there are
public void   add(String word, double prob)                   // add a new entry given a word and a probability
public void   add(String word, double prob, String filename)  // add a new entry given a word, probability, and audio filename
public String getAudioFilename(String word)                   // given a word, return audio filename, "" if word not found or no audio file
public double getProb(String word)                            // given a word, return probability, 0.0 if word not found
public String matchPattern(String pattern)                    // find a word matching this pattern, "" if no match
public String getRandomWord()                                 // draw a random word based on the probabilities
Here is the API you should implement in DictEntry.java:
public class DictEntry
------------------------------------------------------------------------------------------------------------------------------
public         DictEntry(String word, double prob)                  // create a new entry given a word and probability
public         DictEntry(String word, double prob, String filename) // create a new entry given a word, probability, and audio filename
public String  getAudio()                                           // getter for audio filename
public String  getWord()                                            // getter for the word 
public double  getProb()                                            // getter for the probability
public boolean matchPattern(String pattern)                         // does this word match the given pattern?
Audio playback. For this program, we need to play a series of audio files, waiting for each to finish before the next is played. StdAudio cannot do this (plus it seems to crash on Linux). We will instead use a new class AudioFile.java. You'll need to place this file in your working directory. AudioFile has normal instance methods (not static methods like StdAudio). You will need to create an object using the filename as the parameter to the constructor. For this assignment, you want to use the playBlocking() method. Here is an example of using the class:
AudioFile sound = new AudioFile("word_audio/quick.wav");
sound.playBlocking();

How do I match a string against a regular expression? Luckily all the work has been done for you. The String class has a the method public boolean matches(String regex).

How do you separate the columns in your output? We added a tab character \t after printing each field. This makes it align nicely so long as the pattern or word isn't too long.

How do I draw a word uniformly from the dictionary entries? The probabilities of the words sum to one. So to draw one randomly, do the following: My crashes because it can't find the audio file. What is going on? In the folder where you are running your program (i.e. where you are doing java SpeakText < dict5k.txt ), you need to extract the word_audio folder.
Extra credit. Create a new client program SpeakT9.java that works like SpeakText.java except the input are telephone keypad numbers instead of letters. You've just created a basic version of the patented predictive technology T9. Example run:
% java SpeakT9 48 927 843 2378 63 84637 < dict5k.txt 
Read in 5000 dictionary entries.
48      it      0.00255839      word_audio/it.wav
927     was     0.00676185      word_audio/was.wav
843     the     0.00534691      word_audio/the.wav
2378    best    3.60753E-4      word_audio/best.wav
63      of      0.00647559      word_audio/of.wav
84637   times   2.42175E-4      word_audio/times.wav

Submission. Submit your programs SpeakText.java, Dict.java, DictEntry.java and any extra credit files using Moodle. Be sure each submitted source file has the required header with your name, username, and a description of the program.

Copyright © 2011 by Keith Vertanen.

Page last updated: August 16, 2012