pigJava

We’re at the end of week 1, semester 2, and today we had our first programming tutorial since the winter break. While my results from semester 1 had been quite good, I still felt a little rusty, so it was good that our lecturer wasted no time on niceties and spent the entire 2 hour session covering new material, in particular, String Manipulation.

We were given an exercise sheet with 6 tasks to complete, each related to manipulating strings, and each successive task a little more challenging. I’d like to step through my solution to the first task, a program that was to take a word, and convert it to “pig latin”.

The key to this problem is identifying if a word begins with a vowel or a consonant. For the former, you simply append “way” to the word, whilst for the latter you move the first letter to the end, and append “ay”.

For example, James becomes amesJay, whilst Adam becomes Adamway.

Building Blocks

import javax.swing.JOptionPane;
public class pigJava
{
  public static void main(String [] args)
  {
    String userInput = "", pattern = "[a-zA-Z]{1,}";
    String firstChar = "", vowels  = "aeiou", result = "";
    boolean validInput = false;

I imported JOptionPane as that’s how the task requested the input and output to be displayed. After that I declared a number of Strings, userInput will hold whatever string the user types at the prompt, pattern is a simple regular expression that accepts at single word with no spaces.

Then I have an empty string for putting the first letter of the word into later, another empty string for the eventual output, and a string containing all the vowels. Finally I have a boolean value, which I set to false.

The first interesting part of this task was the regular expression [a-zA-Z]{1,}.

For this task, I wasn’t concerned about punctuation or other special characters, so the only characters that are accepted are A through Z, both lowercase and uppercase. This is declared in [a-zA-Z].

Then, I wanted to only accept a single word. In this case, because the first part of the expression will exclude any non-letter characters, including spaces, for the second half of the expression I just had to specify that I wanted at least 1 letter, hence the comma after the 1 in {1,}.

Validate input

while (!(validInput))
{
  userInput = JOptionPane.showInputDialog(null,"Enter word");
  if ((userInput == null) || (userInput.matches(pattern)))
      validInput = true;
  else
      JOptionPane.showMessageDialog(null,"Invalid Input");
}

This block of code is a while loop that prompts the user for input. The loop will continue as long as the boolean validInput is false. while (!(validInput)) .

Because we only want the user to input a single word, with no punctuation, we can use (userInput.matches(pattern)) to check if the string entered matches the conditions outlined in the regular expression we created earlier.

Also, the user may wish to quit the program without entering anything, hence (userInput == null) also flips validInput to true. In a JOptionPane window, clicking on cancel will return null.

Generating output

if (userInput != null)
{
  firstChar = (userInput.substring(0,1)).toLowerCase();
  if (vowels.indexOf(firstChar) != -1)
      result = userInput + "way";
  else
      result = userInput.substring(1)+firstChar+"ay";
  JOptionPane.showMessageDialog(null,result);
}

The first line of this block is an if statement, that we fall into so long as the user hasn’t clicked on cancel (userInput != null).

The first thing we need to do then, is to determine if the first letter of the given word is a vowel or consonant. In order to isolate the first letter, we can use userInput.substring(0,1).

The substring method takes either 1 or 2 arguments as indexes of a string, and pulls out either everything after the first argument, or when provided with 2 arguments, everything from arg 1 up to, but not including arg 2. In this case, we’ve provided 0 and 1, in order to strip out only the first index.

At this point, I also convert the first letter to lowercase using .toLowerCase(), just to make the check for vowels easier later.

At the start of the program I created a string called vowels, containing “aeiou”. I did this so that I can use a string method indexOf() at this point to see if firstChar is a vowel or not. (vowels.indexOf(firstChar) will return -1 if it doesn’t find firstChar anywhere in the vowels string. Otherwise it will return an integer value of the index at which firstChar appears in the vowels string.

Either way, I can then use if (vowels.indexOf(firstChar) != -1), and as long as the returned value is not -1, my firstChar is definitely a vowel, and will fall into the first part of the if statement. At this point, I just concatenate the original input with “way”, result = userInput + "way";.

If indexOf does return -1, then we know the letter is a consonant. In this case I use result = userInput.substring(1)+firstChar+"ay" to create a substring of the original input made up of everything after the first letter, then I merge on the first letter, and finally merge on “ay”, and store this all in result.

Finally, I output my result to the user, and Robert is your Father’s brother.

Conclusion

This is the first time I’ve tried this, by which I mean writing about my programming, writing in Markdown, or setting up a page with Jekyll. I’d love to get any feedback on what about this didn’t land quite right, what worked, and what kind of things I can do in the future!

Written on January 25, 2017